C語言——陣列名、取陣列首地址的區別(一)
目錄: 1. 開篇 2. 論陣列名array、&array的區別 3. array、&array的區別表現在什麼地方 4. 討論 5. 參考 1.開篇 很多部落格和貼吧都有討論這個話題,各有自己的表述方式,今天在他們的基礎上我將繼續試著以我自己理解的方式總結一下,歡迎大家的審閱和指評。
2.論陣列名array、&array的區別——省政府和市政府的區別
例如:
int array[4] = {0};
總所周知,其中的&array是整個陣列array的首地址,array是陣列首元素的首地址(和&array[0]一樣),其值相同,但是“意義不同”。
3.那麼,到底“意義不同”表現在什麼地方呢? 首先,試問下面幾行程式碼分別代表的什麼意思呢?這樣操作有何意義呢?
array;
array + 1;
&array;
&array[0] + 1;
&array + 1;
- 1
- 2
- 3
- 4
- 5
下面一步一步的來討論這個不同表現在什麼地方。
/**********************************************************************
* File: array_name.c
* Copyright (C) jingzi123456789, All Rights Reserved!
* Description:
* The difference between the array name and address of the array name
* Version: 1.0
* Date created: 16:48,26/03/2017
* Author: jingzi123456789
*
* ----------------------- Revision History: ----------------------------
* <author> <data> <desc>
*
***********************************************************************/
#include <stdio.h>
#ifndef _STDIO_H
#define _size_ (5)
#endif
int main()
{
int array[_size_] = {0};
printf(" array = %p\n", array);
printf(" &array = %p\n", &array);
printf(" array + 1 = %p\n", array + 1);
printf("&array[0] + 1 = %p\n",&array[0] + 1);
printf(" &array + 1 = %p\n", &array + 1);
printf("\n");
printf(" sizeof(array) = %d\n",sizeof(array));
printf("sizeof(&array) = %d\n",sizeof(&array));
printf("\n");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
首先,試著分析一下這段程式。我們知道array是陣列首元素的首地址(和&array[0]一樣),&array是整個陣列array的首地址。在第2節中,已經說明了二者的值相同,但是“意義不同”。這就好比,陝西的省政府在西安,而西安市的市政府也在西安,兩個政府都在西安,但其代表的意義完全不同。
那麼,對二者地址分別+1,會產生什麼效果呢?“+1”指的是一般加法(2+1==3)那樣加一嗎?假設陣列array的首元素的首地址為0x0011FF00,這裡“array + 1”的結果會不會是0x0011FF01呢,“&array + 1”的結果會是0x0011FF01?如果不是的話,那會是一個什麼值,並且為什麼會出現這種結果呢?
然後,在回答以上的問題,先通過編譯器VC++6.0在32位系統上編譯執行,根據列印輸出的結果再做討論。注意:對於sizeof(int),32位系統下為4位元組。
4.討論: (1)可以發現array和&array的值是一樣的,都是0012FF34。對array+1,結果不是簡單的加法那樣,即並不是0012FF35,而是0012FF38;由於array[0]和array一樣,都是陣列首元素的首地址,+1後的結果相同。然而,&array+1的結果卻是0012FF48。另外,分別對array和&array求位元組長度發現是一樣的(結果20是一個十進位制數)。
(2)這裡會涉及到一下幾點知識:
- 一般情況下宣告一個數組之後,比如int array[5],陣列名array就是陣列首元素的首地址,而且是一個地址常量。但是,在函式宣告的形參列表中除外。
- 在C中, 在幾乎所有使用陣列的表示式中,陣列名的值是個指標常量,也就是陣列第一個元素的地址。 它的型別取決於陣列元素的型別: 如果它們是int型別,那麼陣列名的型別就是“指向int的常量指標“。——《C和指標》
- 在以下兩中場合下,陣列名並不是用指標常量來表示,就是當陣列名作為sizeof操作符和單目操作符&的運算元時。 sizeof返回整個陣列的長度,而不是指向陣列的指標的長度。 取一個數組名的地址所產生的是一個指向陣列的指標,而不是一個指向某個指標常量的指標。所以&a後返回的指標便是指向陣列的指標,跟a(一個指向a[0]的指標)在指標的型別上是有區別的。——《C和指標》
- “+1”就是偏移量問題:一個型別為T的指標的移動,是以sizeof(T)為移動單位。 即array+1:在陣列首元素的首地址的基礎上,偏移一個sizeof(array[0])單位。此處的型別T就是陣列中的一個int型的首元素。由於程式是以16進製表示地址結果,array+1的結果為:0012FF34+1*sizeof(array[0])=0012FF34+1*sizeof(int)=0012FF38。 即&array+1:在陣列的首地址的基礎上,偏移一個sizeof(array)單位。此處的型別T就是陣列中的一個含有5個int型元素的陣列。由於程式是以16進製表示地址結果,&array+1的結果為:0012FF34+1*sizeof(array)=0012FF34+1*sizeof(int)*5=0012FF48。注意1*sizeof(int)*5(等於00000014)要轉換成16進位制後才能進行相加。
5.參考