關於數組,一些必會的數組運算
//一維數組
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
// 4*4=16 sizeof(數組名)代表整個數組的長度
printf("%d\n",sizeof(a+0));
// 4 a+0 代表第一個元素的地址
printf("%d\n",sizeof(*a));
// 4 a=&a[0] *a=a[0],第一個元素
printf("%d\n",sizeof(a+1));
// 4 a+1 代表第二個元素的地址
printf("%d\n",sizeof(a[1]));
// 4 a[1] 第二個元素
printf("%d\n",sizeof(&a));
// 4 &a 代表取整個數組的地址 另:vc6.0下 結果爲 16,錯誤!
//(&爲取地址符,地址長度爲4個字節或者8個字節,跟平臺有關,32位平臺地址爲4個字節)
printf("%d\n",sizeof(&a+1));
// 4 &a+1 表示指向下一個數組
printf("%d\n",sizeof(&a[0]));
// 4 &a[0] 第一個元素的地址
printf("%d\n",sizeof(&a[0]+1));
// 4 &a[0]+1 第2個元素的地址
解釋:
sizeof(…)是運算符,參數可以是數組、指針、類型、對象、函數等。
它的功能是:獲得保證能容納實現所建立的最大對象的字節大小。
上面一組算式中sizeof()中的含義,由下圖可直觀的看到:
再看下一組計算:
//字符數組
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
// 6 整個數組字節長度
printf("%d\n", sizeof(arr+0));
// 4 首元素地址
printf("%d\n", sizeof(*arr));
// 1 第一個元素
printf("%d\n", sizeof(arr[1]));
// 1 第二個元素
printf("%d\n", sizeof(&arr));
// 4 整個數組的地址
printf("%d\n", sizeof(&arr+1));
// 4 下一個數組的地址
printf("%d\n", sizeof(&arr[0]+1));
// 4 第二個元素的地址
printf("%d\n", strlen(arr));
// 10(假定) strlen以'\0'爲結尾,以上數組無法計算,結果爲隨機值,假定結果爲10,方便下面討論
printf("%d\n", strlen(arr+0));
//10
printf("%d\n", strlen(*arr));
// 錯誤 (*arr爲首元素,strlen()中參數類型爲char * ,傳進來是 char ,類型不匹配。從這位地址開始往後到‘\0’結束,所以此處放的是首元素時,就被當成地址來處理,就有可能無法訪問該位置的內存)
printf("%d\n", strlen(arr[1]));
//錯誤 (原因同上)
printf("%d\n", strlen(&arr));
//10
printf("%d\n", strlen(&arr+1));
//4(10-6) (&arr+1 表示指向下一個數組,數組內容未知)
printf("%d\n", strlen(&arr[0]+1));
//9(10-1) (第二個元素的地址)
VS2013監視如下:
再來一組:
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4
printf("%d\n", sizeof(p+1)); //4
printf("%d\n", sizeof(*p)); //1
printf("%d\n", sizeof(p[0])); //1
printf("%d\n", sizeof(&p)); //4
printf("%d\n", sizeof(&p+1)); //4
printf("%d\n", sizeof(&p[0]+1)); //4
printf("%d\n", strlen(p)); //6
printf("%d\n", strlen(p+1)); //5 (p表示首元素地址,p+1表示第二個元素)
printf("%d\n", strlen(*p)); //錯誤 傳參類型不匹配(*爲解引用,*p爲97'a')
printf("%d\n", strlen(&p[0])); //6
printf("%d\n", strlen(&p)); //隨機 (&p代表指針變量p的地址,見下圖)
printf("%d\n", strlen(&p+1)); //隨機(同上)
printf("%d\n", strlen(&p[0]+1)); //5
下圖可看出&p代表的含義:
再來一組二維數組的計算:
//二維數組
int a[3][4] = {0};
printf("%d\n",sizeof(a)); //48
printf("%d\n",sizeof(a[0][0])); //4
printf("%d\n",sizeof(a[0])); //16
printf("%d\n",sizeof(a[0]+1));
//4 a[0]代表第一個元素(第一個元素爲4個元素的一維數組),a[0]+1代表第一行的第二個元素,也就是a[0][1]
printf("%d\n",sizeof(a+1));
//4 a爲首元素(這裏的元素爲一維數組)地址,a+1代表第2行的地址
printf("%d\n",sizeof(&a[0]+1));
//4 &a[0]+1等價於a+1
printf("%d\n",sizeof(*a));
//16 *a代表首元素,二位數組首元素爲{0,0,0,0},即爲a[0]/*(a+0)
printf("%d\n",sizeof(a[3]));
//16 a[3]代表第四個元素,數組的下一個元素可以訪問,不能寫入。
a[3][4]二維數組可看作有三個“元素”的一維數組,這三個“元素”分別是{0,0,0,0},{0,0,0,0},{0,0,0,0},這樣一解釋上面的*a、a[3]就不難解釋了。
**對於多維數組來說,只有最後一箇中括號的數值不能省略,其他的課省略。例:a[ ][5]
**要看一個數組裏有幾個元素,以第一個中括號裏的值爲準。例:a[2][4] ->2個元素 -> 每個元素爲有4個元素的一維數組。
上圖:
總結:
數組名代表整個數組的時候只有兩種情況:
sizeof(數組名),這裏的數組名錶示整個數組。
&數組名,這裏的數組名錶示整個數組。
按例上圖~康娜