C語言中“陣列名”和“&陣列名”
C語言中 陣列名
和 &陣列名
== 實驗環境 ==
1. 編譯器:gcc 5.4.0
2. 作業系統:Ubuntu 16.04 x86_64
緣起
本以為此知識點我已熟練掌握,可是最近應用的時候還真給記混淆了。所以寫篇文章加深印象。
Show me the code
廢話少說,show me the code
.
#include <stdio.h>
int main(void)
{
int array[5] = {0};
printf("1. array = %p\n", array);
printf("2. &array = %p\n" , &array);
printf("3. &array[0] = %p\n", &array[0]);
printf("4. array + 1 = %p\n", array + 1);
printf("5. &array[0] + 1 = %p\n", &array[0] + 1);
printf("6. &array + 1 = %p\n", &array + 1);
printf("7. sizeof(array) = %lu\n", sizeof(array));
return 0;
}
請你思考一分鐘,然後再看答案。
…
…
執行結果是:
討論
在絕大多數關於陣列的表示式中,陣列名代表指標常量,這個指標指向陣列首個元素。從數值上講,陣列名錶示的值就是首個元素的地址。 從結果的第1行和第3行,第4行和第5行,都可以驗證這一點,即array
的值就等於&array[0]
的值。
剛才已經說過,陣列名代表指標常量,且這個指標指向陣列首個元素。當對這個指標進行加減的時候,以一個數組元素為顆粒度。例子中的陣列元素為整型,所以陣列名加1時地址加4. 對比第4行和第1行,可以驗證。
但是,在以下2種語境中,陣列名並不是上面說的指標常量。
1. sizeof(陣列名)
2.
&陣列名
對於1,sizeof(陣列名)
返回整個陣列的長度,而不是指標常量的長度。 結果的第7行,返回20(=4*5),而不是返回8(因為地址寬度是64位,所以指標佔8位元組)。
對於2,對陣列名取地址所產生的值的型別是一個指向整個陣列的指標,而不是一個指向指標常量的指標。所以&array
的型別是指向整個陣列的指標,而array
是指向array[0]
的指標,雖然在數值上相同(結果的第1行和第2行),但是在型別上不同。
正因為它們的型別不同,所以在加1或減1的時候,顆粒度不同。array
以一個數組元素為顆粒度,例子中的陣列元素為整數,所以array
加1時地址加4(對比結果的1、4兩行);而&array
以整個陣列為顆粒度,例子中的陣列為有5個元素的整型陣列,所以&array
加1時,地址加20(對比結果的2、6兩行)。
總結
絕大多數情況下,陣列名代表指標常量,這個指標常量指向陣列首個元素。從數值上講,陣列名的值就是首個元素的地址。當對這個指標常量進行加減的時候,以一個數組元素為顆粒度。
在
sizeof(陣列名)
和&陣列名
這2種語境中,陣列名並不是上面說的指標常量。sizeof(陣列名)
返回整個陣列的長度,而不是指標常量的長度。&陣列名
的型別是一個指向整個陣列的指標,而不是一個指向指標常量的指標。陣列名
和&陣列名
雖然在數值上相同,但是在型別上不同——陣列名
是指向首個元素的指標,&陣列名
是指向整個陣列的指標。在指標加減整數的時候,前者以一個元素為顆粒度,後者以整個陣列為顆粒度。