給陣列賦值的一些小坑
陣列初始化問題:int a[3]={0}和int a[3]={1}的區別
陣列定義同時初始化是個常見的問題,比如,int a[3]={0},其中a[0],a[1],a[2]這三個值都為0。
如果這樣定義,同時賦值:int a[3]={1},是不是意味著a[0]=1,a[1]=1,a[2]=1呢?這是一個很容易出錯的問題,答案肯定不是這樣,筆者在多個編譯器上試過,結果只有a[0]=1,而a[1]=0,a[2]=0。
如果要追究原因,只能去問搞編譯器的人。語言有時候很難說為什麼這樣,或許只能方便而已。這是vc6.0下的彙編:
……
4: int a[3]={0};
00401028 mov dword ptr [ebp-0Ch],0 ;
0040102F xor eax,eax ;暫存器eax清零,eax的值為0
00401031 mov dword ptr [ebp-8],eax ;把eax的值賦給a[1],所以a[1]=0
00401034 mov dword ptr [ebp-4],eax;把eax的值賦給a[2],所以a[1]=0
5: int b[3]={1};
00401037 mov dword ptr [ebp-18h],1;b[0]=1
0040103E xor ecx,ecx;暫存器ecx清零, ecx的值為0
00401040 mov dword ptr [ebp-14h],ecx;把
00401043 mov dword ptr [ebp-10h],ecx;把ecx的值賦給b[2],所以b[1]=0
int陣列為什麼一般不能用memset初始化每個元素
對於整數型陣列,若要是初始化為非0的值時應該使用for迴圈而對於字元型 或 0 應該使用memset 函式
如下是可以的,能把陣列中的元素值都設定成字元1,
- #include <iostream>
- #include <cstring>
- usingnamespace std;
- int main()
- {
- char a[5];
- memset(a,'1'
- for(int i = 0;i < 5;i++)
- cout<<a[i]<<" ";
- system("pause");
- return 0;
- }
而,如下程式想吧陣列中的元素值設定成1,卻是不可行的
- #include<iostream>
- #include <cstring>
- usingnamespace std;
- int main()
- {
- int a[5];
- memset(a,1,5);//這裡改成memset(a,1,5 *sizeof(int))也是不可以的
- for(int i = 0;i < 5;i++)
- cout<<a[i]<<" ";
- system("pause");
- return 0;
- }
問題是:
1,第一個程式為什麼可以,而第二個不行,
2,不想要用for,或是while迴圈來初始化inta[5];能做到嗎?(有沒有一個像memset()這樣的函式初始化)
答:
1.因為第一個程式的陣列a是字元型的,字元型佔據記憶體大小是1Byte,而memset函式也是以位元組為單位進行賦值的,所以你輸出沒有問題。而第二個程式a是整型的,使用memset還是按位元組賦值,這樣賦值完以後,每個陣列元素的值實際上是0x01010101即十進位制的16843009。你看看你輸出結果是否這樣?
2.如果用memset(a,1,20);
就是對a指向的記憶體的20個位元組進行賦值,每個都用ASCII為1的字元去填充,轉為二進位制後,1就是00000001,佔一個位元組。一個INT元素是4位元組,合一起就是1000000010000000100000001,就等於16843009,就完成了對一個INT元素的賦值了。
如何給陣列A初始化為無窮大?
利用上面原理,memset( A, 0x3f,sizeof( A) ),0x3f 轉換成十進位制為63,每個位元組都用ASCII碼為63的字元去填充,轉換成為禁止就是00111111,佔一個位元組,int型4個位元組就是 00111111001111110011111100111111,約等於無窮大