1. 程式人生 > >C語言——陣列名、取陣列首地址的區別(一)

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.參考