溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用本地c/c++提升iOS性能 之二

發(fā)布時間:2020-07-07 13:06:37 來源:網(wǎng)絡(luò) 閱讀:596 作者:iKingLai 欄目:移動開發(fā)

基本的c和c++編程


我將會引導(dǎo)你學(xué)習(xí)一些簡單的c/c++課程,讓你對它有一個基本的了解。Objective-C和c/c++有很多共同點(diǎn),所以在本章你不需要學(xué)習(xí)很多新的概念。理解c/c++同樣能夠幫助你更好的編寫Objective-C,因為Objective-C是C的一個超集。


c編程


c++同樣是c的超集,所以你必須先學(xué)會如何使用c,然后在接下來的部分學(xué)習(xí)c++。我只會討論使用c編程和iPhone編程不同的那部分。


基本數(shù)據(jù)類型和函數(shù)


c的數(shù)據(jù)類型很少:integer,floating point,double precision floating point 和characters。在不同的操作系統(tǒng)中,每一種數(shù)據(jù)類型的二進(jìn)制位是不同的,甚至在iOS的不同版本中也不同。下面的是每種數(shù)據(jù)類型的取值范圍,但是你不應(yīng)該太過依賴于這些信息,尤其是在做重要決定的時候:

  • char:-128到127

  • integer:-32768到+32767

  • float:3.4 e-38 到 3.4 e+38

  • double:1.7 e -308 到 1.7 e +308


還有很多修飾符可以應(yīng)用帶這些基本類型上;例如,short和long可以用在integer上。


short int sh;

long int counterLong;


使用這些修飾符的目的是為integer提供一個更小或更大的范圍;例如,short是16位,long是32位。iOS編譯器能確保short不比int長,long不比int短。


你也可以使用signed和unsigned修飾符。如果你沒有指定任何signed或unsigned,編譯器默認(rèn)使用signed。使用unsigned修飾符,能讓數(shù)據(jù)范圍擴(kuò)大一倍。例如,integer的范圍從0到65535.


通常你只需使用integer。如果你想存儲一個很大的integer,就添加long修飾符。使用short覆蓋int,內(nèi)存優(yōu)化非常小,你基本上可以忽略它。



注意:如果你使用Objective-C,你應(yīng)該使用NSInteger,NSUInteger,和CGFloat。這些是蘋果內(nèi)置的包裝類,它們封裝了底層的實(shí)際數(shù)據(jù)結(jié)構(gòu)。



c沒有Boolean數(shù)據(jù)類型,但是Objective-C有。在c中,如果一個Boolean語句返回true,值是1;否則是0.例如 2==2將返回1,而 2==3將返回0。為了增強(qiáng)代碼的可讀性,你可能需要定義兩個Boolean宏,類似這樣:


   #define TRUE 1

   #define FALSE 0

   int t = (1 == 1);

   if (t == TRUE) {

       // do your work here

   }


盡管c函數(shù)和Objective-C函數(shù)看起來不同,但是你依然需要返回一個值和接收參數(shù)。下面是兩個c函數(shù)的例子:


int pi_value() {

   return 3.14;

}


int add_number(int n1, int n2) {

   return n1 + n2;

}



指針


指針在c編程中是非常重要的。在Objective-C中,你通常會看到Objective-C有同樣的指針概念和語法,例如NSMutableArray *myArray = [NSMUtableArray array]。但是,你不需要知道底層內(nèi)存的細(xì)節(jié),因為在Objective-C中指針可以很簡單的認(rèn)為它是一個對象。但是,如果使用c,你要做的事情將更多,c中指針的概念也更加復(fù)雜。


內(nèi)存指針概念


主存可以看做是一個cell的數(shù)組,每一個cell看做是一個字節(jié),每一個數(shù)據(jù)item存儲在cells的group中。一個char存儲在一個cell,一個integer存儲在兩個cell中,而一個long存儲在4個cell中。每一個cell都可以被數(shù)字化,因此每一個變量將有一個內(nèi)存地址來存儲數(shù)據(jù)。


使用本地c/c++提升iOS性能  之二

圖 9-1 內(nèi)存指針概念


指針是一個變量,它保存了另一個變量的內(nèi)存地址。例如,圖9-1變量p里面的數(shù)據(jù)保存了變量c的內(nèi)存地址。所以我們說,p指向了c,你可以用語句 p = &c 來表示它;&操作符返回變量c的內(nèi)存地址,然后賦值給p。&只能應(yīng)用在內(nèi)存中的變量,數(shù)組和對象,不能用在表達(dá)式或常量上。指針的另一個操作符是*;當(dāng)它應(yīng)用到指針,指針操作符然后給定地址內(nèi)存中的內(nèi)容。這個過程通常稱為解引用。這邊有一個源代碼顯示了是如何進(jìn)行工作的:


int x = 1, y = 2, a[3];
int *ip; // ip is a pointer that can only point to integer

ip = &x; // ip now points to x
y = *ip; // y is now 1, because you return the data pointed by ip*ip = 0; // x is now 0, I set the data pointed by p to be 0
ip = &a[0]; // ip now points to the first element of array a


值傳遞和引用傳遞


在c編程中,你參數(shù)傳遞有兩種方式:值傳遞和引用傳遞。通過值傳遞把參數(shù)傳遞給函數(shù)是通常的方式。


int add(int t1, int t2) {

   return t1 + t2;

}


然而,值傳遞是不起作用的,如果你想要交換兩個變量的值:


void swap(int x, int y) {

   int temp;

  temp = x;  

   x = y;  

   y = temp;

}


int main() {

   int x = 3, y = 4;

   swap (x, y);

}


問題是在函數(shù)返回后,里面的兩個變量值并沒有交換。當(dāng)swap方法被調(diào)用的時候,x和y的值會被拷貝然后再傳遞給函數(shù)swap(3, 4)。因此,原始的變量值并沒有改變。


如果你想要改變存儲在變量x和y的內(nèi)部值,你需要使用引用傳遞。通過引用傳遞,x和y的內(nèi)存地址被傳遞進(jìn)來。使用x和y的內(nèi)存地址,你能夠非常簡單的修改存儲在她們內(nèi)存的值了。


void swap(int *px, int *py) {
   int temp;
   temp = *px; // temporarily store the value inside the memory of x

   *px = *py; // set the value inside the memory of x.
   *py = temp; // set the value inside the memory of y.

}


int main() {
   int x = 3, y = 4;

   swap (&x, &y);

}


圖 9-2 能夠讓你更好的理解這個過程。

使用本地c/c++提升iOS性能  之二


高級數(shù)據(jù)類型


在c中還有一些高級數(shù)據(jù)類型:array(數(shù)組),string(字符串)和struct(結(jié)構(gòu)體)。這些在Objective-C中都是支持的,但是你應(yīng)該謹(jǐn)慎的使用,因為會使得代碼難以理解,后續(xù)維護(hù)也變得更加困難。所有這些數(shù)據(jù)結(jié)構(gòu)在Objective-C中都有對應(yīng)的包裝類,使得代碼更加面向?qū)ο?。但是,在很多情況下,你仍然需要使用c數(shù)據(jù)結(jié)構(gòu)來提升性能或處理來自c/c++庫的調(diào)用結(jié)果。


Array數(shù)組


在Objective-C中,你通常會使用NSArray或NSMutableArray對象來表示一個數(shù)組。但是,在c中,你沒有這些概念,因此你應(yīng)該集中在數(shù)組的基本概念上。在c中為了定義一個數(shù)組,你需要提前知道數(shù)組的長度,類似這樣的定義:


int a [10]; // an array with maximum ten elements
a[0], a[1], a[2] ... a[9] is the first, second ... tenth elements of the array


指針和數(shù)組有非常密切的關(guān)系。


int *pa;

pa = &a[0];


這個指針賦值代碼將pa指向數(shù)組的第一個元素。根據(jù)指針那部分解釋的,賦值語句 x = *pa,x包含了a[0]的值。


你可以通過簡單的算術(shù)運(yùn)算來移動指針指向數(shù)組內(nèi)的不同元素,pa+1會返回下一個元素的地址,pa-1返回上一個元素的地址。圖9-3展示了指針在數(shù)組內(nèi)部的算術(shù)運(yùn)算。


使用本地c/c++提升iOS性能  之二

這些計算并不依賴于數(shù)組內(nèi)存變量的類似或大小。因此,(pa + i)將返回數(shù)組中的第i個元素的地址。另一個在數(shù)組和指針之間非常重要的關(guān)系是你可以使用 *(aa + i)來引用a[i]。


在數(shù)組和指針之間有一個不同點(diǎn):指針是一個變量,所以pa = a和pa++都是合法的。然而,a = pa和a++是不合法的。


String字符串


在c中字符串常量,例如 "I am Khang",一個以'\0'結(jié)尾的字符數(shù)組,這樣程序就能夠找到數(shù)組的結(jié)束部分。因為string是一個字符數(shù)組,你可以簡單的將它賦值給指針。


char *pmessage;
pmessage = "I am Khang";


你可以把string看做是一個正常的數(shù)組或指針那樣進(jìn)行操作,如下面的源代碼:


void my_string_copy (char *s, char *t) {

   while (*s++ = *t++) ;

}


my_string_copy函數(shù)是非常簡單的;它有兩個字符指針,將string t(通過字符指針來表示)中的字符元素賦值給賦值給string s。



注意:當(dāng)你把數(shù)組作為一個參數(shù)傳遞給函數(shù)時,c會自動的將它轉(zhuǎn)換為指向數(shù)組的指針。



這里有另一個例子,使用了字符數(shù)組,但是并沒有使用指針,它展示了數(shù)組和指針的內(nèi)部轉(zhuǎn)換:


int my_string_length(char *s) {

   int i = 0;
   while (s[i] != '\0') {

           i++;

   }

   return i;

}






向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI