C字符串數組初始化相關問題總結
在C語言編程中,當我們聲明一個字符串數組的時候,常常需要把它初始化為空串。總結起來有以下三種方式:
- (1) char str[10]="";
- (2) char str[10]={'\0'};
- (3) char str[10]; str[0]='\0';
第(1)(2)種方式是將str數組的所有元素都初始化為'\0',而第(3)種方式是只將str數組的第一個元素初始化為'\0'。如果數組的size非常大,那么前兩種方式將會造成很大的開銷。
所以,除非必要(即我們需要將str數組的所有元素都初始化為0的情況),我們都應該選用第(3)種方式來初始化字符串數組。
1. 基本問題
數組可以初始化,即在定義時,使它包含程序馬上能使用的值。
例如,下面的代碼定義了一個全局數組,並用一組Fibonacci數初始化:
1 int iArray[10]={1,1,2,3,5,8,13,21,34,55); //初始化 2 void main() 3 { 4 //... 5 }
初始化數組的值的個數不能多於數組元素個數,初始化數組的值也不能通過跳過逗號的方式來省略,這在C中是允許的,但在C++中不允許。
例如,下面的代碼對數組進行初始化是錯誤的:
1 int arrayl[5]={1,2,3,4,5,6}; //error-初始化值個數多於數組元素個數 2 int array2[5]={1,,2,3,4}; //error:初始化值不能省略 3 int array3[5]={1,2,3,}; //error:初始化值不能省略 4 int array4[5]={}; //error:語法格式錯誤 5 void main() 6 { 7 //... 8 }
初始化值的個數可少於數組元素個數。當初始化值的個數少於數組元素個數時,前面的按序初始化相應值, 后面的初始化為0(全局或靜態數組)或為不確定值(局部數組)。
例如,下面的程序對數組進行初始化:
1 //********************* 2 //** ch7_2.cpp ** 3 //********************* 4 #include <iostream.h> 5 6 int array1[5]={1,2,3}; 7 static int array2[5]={1}; 8 9 void main() 10 { 11 int arr1[5]={2}; 12 static int arr2[5]={1,2}; 13 14 int n; 15 cout <<"global:\n"; 16 for(n=0; n<5; n++) 17 cout <<" " <<array1[n]; 18 19 cout <<"\nglobal static:\n"; 20 for(n=0; n<5; n++) 21 cout <<" " <<array2[n]; 22 23 cout <<"\nlocal:\n"; 24 for(n=0; n<5; n++) 25 cout <<" " <<arr1[n]; 26 27 cout <<"\nlocal static:\n"; 28 for(n=0; n<5; n++) 29 cout <<" " <<arr2[n]; 30 cout <<endl; 31 }
運行結果為:
global:
l 2 3 0 0
global static:
1 0 0 0 0
local:
2 23567 23567 23567 23567
local static:
1 2 0 0 0
例中,全局數組和全局靜態數組的初始化是在主函數運行之前完成的,而局部數組和局部靜態數組的初始化是在進入主函數后完成的。
全局數組arrayl[5]對於初始化表的值按序初始化為1,2,3,還有兩個元素的值則按默認初始化為0。
全局靜態數組array2[5]與全局數組的初始化情況一樣,初始化表值(1)表示第1個元素的值,而不是指全部數組元素都為1。
局部數組arrl[5]根據初始化表值的內容按序初始化, 由於初始化表值只有1個,所以還有4個元素的值為不確定。在這里均為數值23567。
局部靜態數組arr2[5]先根據初始化表按序初始化,其余3個數組元素的值默認初始化為0。
2.初始化字符數組
初始化字符數組有兩種方法,一種是:
char array[10]={"hello"};
另一種是:
char array[10]={'h','e','l','l','\0'};
第一種方法用途較廣,初始化時,系統自動在數組沒有填值的位置用,'\0'補上。另外, 這種方法中的花括號可以省略,即能表示成:
char array[10]="hello";
第二種方法一次一個元素地初始化數組,如同初始化整型數組。這種方法通常用於輸入不容易在鍵盤上生成的那些不可見字符。
例如,下面的代碼中初始化值為若干制表符:
char chArray[5]={'\t','\t','\t','\t','\0');
這里不要忘記為最后的,'\0'分配空間。如果要初始化一個字符串"hello",那為它定義的數組至少有6個數組元素。
例如,下面的代碼給數組初始化,但會引起不可預料的錯誤:
char array[5]="hello";
該代碼不會引起編譯錯誤,但由於改寫了數組空間以外的內存單元,所以是危險的。
3.省略數組大小
有初始化的數組定義可以省略方括號中的數組大小。
例如,下面的代碼中數組定義為5個元素:
int a[]={2,4,6,8,10};
編譯時必須知道數組的大小。通常,聲明數組時方括號內的數字決定了數組的大小。有初始化的數組定義又省略方括號中的數組大小時,編譯器統計花括號之間的元素個數,以求出數組的大小。
例如,下面的代碼產生相同的結果:
static int a1[5]={1,2,3,4,5};
static int a2[]={1,2,3,4,5};
讓編譯器得出初始化數組的大小有幾個好處。它常常用於初始化一個元素個數在初始化中確定的數組,提供程序員修改元素個數的機會。
在沒有規定數組大小的情況下,怎么知道數組的大小呢? sizeof操作解決了該問題。 例如,下面的代碼用sizeof確定數組的大小:
1 //********************* 2 //** ch7_3.cpp ** 3 //********************* 4 5 #include <iostream.h> 6 7 void main() 8 { 9 static int a[]={1,2,4,8,16}; 10 for(int i=0; i<(sizeof(a)/sizeof(int)); i++) 11 cout <<a[i] <<" "; 12 cout <<endl; 13 }
運行結果為:
1 2 4 8 16
sizeof操作使for循環自動調整次數。如果要從初始化a數組的集合中增刪元素,只需重新編譯即可,其他內容無須更動。
每個數組所占的存儲量都可以用sizeof操作來確定! sizeof返回指定項的字節數。sizeof常用於數組,使代碼可在16位機器和32位機器之間移植:
對於字符串的初始化,要注意數組實際分配的空間大小是字符串中字符個數加上末尾的,'\0',結束符。
例如,下面的代碼定義一個字符數組:
1 //********************* 2 //** ch7_4.cpp ** 3 //********************* 4 5 #include <iostream.h> 6 7 void main() 8 { 9 char ch[]="how are you"; 10 11 cout <<"size of array: " <<sizeof(ch) <<endl; 12 cout <<"size of string: " <<strlen("how are you") <<endl; 13 }
運行結果為:
size of array:12
size of string:ll
例中,數組大小為12,而字符串長度為11。
省略數組大小只能在有初始化的數組定義中。
例如,下面的代碼將產生一個編譯錯誤:
int a[];//error:沒有確定數組大小
在定義數組的場合,無論如何,編譯器必須知道數組的大小。