中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

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

發布時間:2020-07-21 01:23:06 來源:網絡 閱讀:591 作者:iKingLai 欄目:移動開發

Struct結構體


c沒有面向對象編程的概念。所以為了創建一個復雜的數據結構(不是基本數據類型和數組),你必須使用結構體。在某些Objective-C代碼中,你可能甚至經常看到結構體被使用,這樣做是為了節省內存。


例如,CGPoint,CGRect,和CGSize都是結構體。蘋果開發者把他們作為結構體是因為在iPhone中構建views的時候要頻繁的使用到。你可以在Objective-C中使用結構體。


struct point {  

   int x;

   int y;

};


struct point add_point(struct point p1, struct point p2) {

   p1.x += p2.x;
   p1.y += p2.y;
   return p1;

}


如果你要傳遞一個大的結構體數據給函數,你應該考慮傳遞結構體指針,這樣能夠避免拷貝整個結構體(因為是值傳遞)。在其他通常情況下你會看到結構體指針。


struct point origin;
struct point *porigin;
porigin = &origin;
printf("origin is (%d, %d) \n" , (*porigin).x , (*porigin ).y );


動態內存分配


和Objective-C比較,c中的內存管理有一些相同點和不同點。在c中,你可以create和allocate內存給對象;如果你為一個對象分配了內存,你不要手動的deallocate/free這個對象,釋放內存。在Objective-C的autorelease或Autorelease Pool中,沒有這樣的概念。


為了對c中的內存管理有一個很好的理解,你必須記住4個重要的函數,如表格9-1

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

  • malloc:你可以申請一個指定大小的內存快,然后返回一個void類型的指針。你可以把這個指針轉換成你指定的類型,如:


       my_ptr = (cast_type *)malloc(number_of_bytes); // General format
       my_ptr = (int *)malloc (100 * sizeof(int)); // allocate a pointer of integer with size

       //of 100 integer


  • calloc:它通常用來申請多個內存塊,每個塊的大小相同,然后把他們所有字節都設置為0

       my_ptr = (cast_type *)calloc(number_of_elements, size_of_element); // General format

       my_ptr = (int *)calloc (100, sizeof(int)); // allocate a pointer of integer with size

       // of 100 integer


  • free:這個內存管理機制類似于Objective-C:你分配的內存,你需要釋放它。你可以在c中使用free進行釋放。


       free(my_ptr);


  • realloc:有時候你為對象或數組分配的內存不夠,因此你需要改變內存的大小,通過realloc可以用實現。


       realloc(my_ptr, 200 * sizeof(int));


注意:你不能再一次使用函數 malloc/calloc,因為將會擦除你指針指向的內存中存儲的數據。



Linked List 例子


是時候從理論中走出來,然后開始寫代碼了。你將用你學到的知識來解決用鏈表存儲數據的問題。已經在第5章學習了用Ogjective--C來實現。現在,你將學會如何用c寫一個鏈表,在很多情況下,會有更高的性能。


#include <stdio.h>

#include <stdlib.h>

struct Node {
   int  number;
   struct Node *next;

};


為了得到一個鏈表,你需要一個結構體引用自身。節點結構體內部需要有一個link來指向下一個結構體節點。在c中,你可以在頭文件或實現文件中聲明方法接口。


void append_node(struct Node *list, int num);

void display_list(struct Node *list);


int main(void) {

   struct Node *list;

   list = (struct Node *)malloc(sizeof(struct Node));list->number = 0;
   list->next = NULL;

   append_node(list, 1);

   append_node(list, 5);append_node(list, 3);

   display_list(list);

   // delete a list here. free(list) will not work

   return(0);

}


void delete_list(struct Node *list) {

   // do it as your exercise

}


void display_list(struct Node *list) {
   // loop over the list to print the value out.while(list->next != NULL) {

   printf("%d ", list->number);

   list = list->next;}

   printf("%d", list->number);

}


void append_node(struct Node *list, int num) {

// go into the end of the list

while(list->next != NULL)

   list = list->next;

   // set the next property for the last Node object.

   list->next = (struct Node *)malloc(sizeof(struct Node));

   list->next->number = num;
   list->next->next = NULL;

}


你可以看到,因為你的鏈表沒有固定大小,你總是要使用malloc來分配新的元素。在用完鏈表之后,你要刪除它。你需要記住內存管理規則:對于每次調用malloc或calloc,你需要調用free函數;否則,會有內存泄露。像在代碼中的警告注釋,簡單的調用free(list)會導致一些內存泄露。我將delete_list的實現作為一個練習留給你來做。


函數指針


在c中,函數不是一個變量,但是你可以定義一個指針指向它,就像定義指針指向一個整數或結構體。你可以把這些指針放到一個數組中,然后把這些函數指針作為參數傳遞給其他函數。這個和Objective-C中的selector是類似的。


接下來你會看到一個簡單的例子,在快速排序算法中實現了一個比較方法。qsort是c中的一個內置函數,能夠得到一個函數指針,然后使用快速排序算法對數組進行排序。


這是qsort的接口:


void qsort (void *array, int number_of_elements, int size_of_element, int (* comparator)

(const void *, const void *) );


你需要一個比較函數,它接收兩個指針,返回一個整數表示什么值更大。


int compare (const void * a, const void * b) {

       return ( *(int*)a - *(int*)b );

}


然后你可以把它作為參數傳遞給qsort函數。


int main () {

   int values[] = { 40, 10, 100, 90, 20, 25 };
   qsort (values, 6, sizeof(int), compare); // pass in the compare function here.return 0;

}



Bitwise Operators位操作符


位操作運算比加法和減法稍快一些,比乘法和除法快很多。你也許會在一些庫中看到使用位操作符,尤其是用比較老的微處理器寫的。


了解位操作符能夠幫助你操作位,在密集型計算中得到更好的性能。只有幾個位操作符合移位操作符需要記住:NOT, AND, OR, XOR, left shfit,和right shift。

  • NOT   邏輯非,0變1,1變0.

    NOT     0111 = 1 000

  • AND 邏輯與,只要有一個為0,結果就是0;否則為1

    0 1 0 1

    0 0 1 1

AND

      0 0 0 1

  • OR  邏輯或,只要有一個為1,結果就是1;否則為 0


       0 0 1 0

       1 0 0 0

OR

       1 0 1 0

  • XOR 邏輯異或,相同為0,不同為1


       0 1 0 1

       0 0 1 1

XOR

       0 1 1 0


使用這些位操作符,你能夠非常快的改變bit值。如果你不經常使用位操作的話,這看起來會非常的奇怪。我會在Objective-c中給你一個說明。這里有一個使用了位操作的Cocoa Touch Framework中的應用,假設你已經對NSCalendar非常熟悉了。


在一個NSCalendar中,你可以基于一個輸入參數得到一個指定日期的日期組件列表。例如,如果你想要一個NSDataComponent對象,它包含了你想要的日期組件,你可以使用下面的源代碼:


NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;

NSDateComponents *dateComponents = [calendar components:unitFlags

fromDate:startDatetoDate:endDate

options:0];


當方法[calendar components:fromDate:toDate:options] 使用unitFlag被調用時,會檢查調用者需要什么樣的日期組件,然后會返回一個確切的組件類型。這樣讀寫代碼都是非常方便的,只需要使用OR操作符。


在方法[calendar components:fromDate:toDate:options] 中,會使用 AND 操作符檢查unitFlag的值。


BOOL hasYear = (unitFlags & NSYearCalendarUnit) != 0;

BOOL hasMonth = (unitFlags & NSMonthCalendarUnit) != 0;

BOOL hasWeek = (unitFlags & NSWeeCalendarUnit) != 0;
...


現在,我詳細解釋一下內部發生了什么以及是如何工作的。首先,每個flagNSYearCalendarUnit, NSMonthCalendarUnit,等等 )被賦予了一個唯一的二進制值,用這樣的格式來表示:0100,1000。


當你在這三個flags上進行OR操作時,你會得到類似1011這樣的值。你把這個值傳遞給方法

[calendar components:fromDate:toDate:options] 。在這個方法的內部,它會將存儲在內部的每一個flag做AND操作。


1011 & 0100 = 0100there is a NSYearCalendarUnit.

1011 & 1000 = 1000 there is a NSMonthCalendarUnit


相比其他普通的方法(要么傳遞很多參數,要么使用一個很大的枚舉,或者需要一個很大的循環來檢查數據),使用這種方法將會提升你應用程序的性能。


  • 位的移動:當你要乘或除一個2的倍數時,你可以對位進行左移或右移。例如,如果你要乘或除2,4,6,8,16......,你可以考慮使用位的移動,比直接使用乘法或除法性能高很多。你只能在整數上

    進行位的移動。



有兩個移位操作符:左移和右移。整數是以二進制的形式存儲的,例如0000 0110(十進制是6)。


  • 左移:把左邊的位移出去,右邊用0補充。如果你左移了n位,相當于乘了2的n次方。    

    0000 0110 << 1  = 0000 1100 (十進制12)
  • 右移:把右邊的位移出去,左邊用c補充。如果你右移了n位,相當于除了2的n次方。

    0000 0110 >> 1  = 0000 0011(十進制3)      





向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

手游| 宜阳县| 江孜县| 达尔| 吉水县| 益阳市| 澎湖县| 洛宁县| 泗阳县| 密山市| 望都县| 鄂伦春自治旗| 厦门市| 通化县| 贵定县| 滁州市| 女性| 南乐县| 富阳市| 乐安县| 安顺市| 城固县| 天镇县| 龙州县| 巴青县| 雷波县| 普定县| 苍溪县| 南岸区| 新乡县| 慈溪市| 历史| 阿克苏市| 合江县| 桓台县| 新民市| 比如县| 安福县| 兴海县| 新密市| 哈巴河县|