1. 程式人生 > >陣列與字串初始化為空的深入理解

陣列與字串初始化為空的深入理解

正題

1. 一維陣列初始化,可以只給一部分元素賦值,如下

int a[10] = {0,1,2,3,4};
這樣只給前面的5個元素賦值,後5個元素為0。
將char p[8]; 看作是字元陣列的話, charp[8]={0}; 表示第一個元素為0,後面的7個元素也為0;
所以 char p[8] = {}和charp[8]={0}一樣; 8個元素都初始化為0
2.用字串常量來使字元陣列初始化
char p[10] = "china";
前5個元素為‘c’,'h','i','n','a',
第6個元素為‘\0'
後4個元素為空字元,即‘\0'
所以用char p[8] = "";初始化,8個元素都是‘\0';
//'0'表示結束標誌,代表ASCII碼為0的字元


所以用 char p[8] = ""; 和 char p[8] = {0}; 都能夠將8個元素初始化為0;
char p[8] = {0}; 當作字元陣列看待,常規陣列初始化;
char p[8] = "";  用字串常量初始化

附註

#define ARRAYSIZE 2048
voidmain() {
chararrayA[ARRAYSIZE]={0};
chararrayB[ARRAYSIZE];
memset(array,0, ARRAYSIZE);
}

char arrayA[ARRAYSIZE] = {0};
編譯是先arrayA[0]賦值為0, 再呼叫memset初始化其他的陣列元素.

char arrayA[ARRAYSIZE] = {0};


效率很難比用memset高,因為綜上分析,我覺得給一塊記憶體賦值的效率很難超越memset。

語法:

#include <cstring>void*memset(void*buffer,intch,size_tcount);

memset()拷貝chbuffer的前count字元中,並返回buffer。memset()對於以某一值初始化一段記憶體非常有用。例如,這個命令:

constintARRAY_LENGTH=300; charthe_array[ARRAY_LENGTH]; // zero out the contents of the_array memset(the_array,
'\0', ARRAY_LENGTH);

…是非常有效率的方法來設定the_array中的所有值為零。

下表比較了兩種不同的方式來初始化字元陣列:for迴圈和memeset()。隨著初始化資料量的增加,memset()很清晰的做的更快:

耗時 for迴圈 memset
1000 0.016 0.017
10000 0.055 0.013
100000 0.443 0.029
1000000 4.337 0.291

幾條不成熟的建議

1:非必要情況不對記憶體使用memset清零,尤其是大塊記憶體。

2:如某結構體或記憶體塊在使用前會逐一賦值,則不需要對其進行memset初始化。

3:字串的初始化可以對其第一個位元組賦值0。

使用strcpy拷貝的字串不需要進行初始化。

使用strncpy拷貝的字串,建議不要先進行memset全部清零,而是在strncpy後,根據字串實際長度,對字串後一個位元組置零。

在做流程判斷的時,儘量減少使用字串比較,而採用整形或布林量比較。

4:減少結構體轉換和copy程式碼。對結構體尤其是包含長字串的結構體複製時,建議慎用memcpy,而採取逐一賦值的方式。

5: 非必要不使用malloc和free,不但容易造成記憶體洩露,而且動態分配記憶體快時,系統的記憶體堆狀況可能會影響分配效率(比如記憶體碎片很多時)。建議對一些動態分配的陣列,採用定義一個足夠大的陣列方式.(這裡有個問題:區域性變數的最大尺寸是多少呢,也就是說程序棧空間是多少呢?這個應該是有限制的,但是每種作業系統或編譯器的限制是多少呢,應該不能在棧空間裡定義一個幾十M或一個G大的陣列吧?)

6:unix程式是基本上是以程序模式執行的,可以合理使用全域性靜態變數。減少分配記憶體的開銷。在多執行緒程式裡慎用全域性變數