在C語言中,有時候指標和數組等效,有的時候卻不然。
什麼時候不同?
1. 數組名本身就代表一個地址。指標代表地址的地址。所以,指標、數組的定義和可能有的多處的聲明要嚴格匹配!不能將在一個地方定義的數組,在他處聲明為指標。反過來也不行!(詳見C專家p84)的
2. 指標和數組都可以在他們的定義中用字串常量進行初始化。儘管看上去一樣,但底層的實現機制卻不同。定義指標時,編譯器不為指標所指向的對象分配空間,它只是分配指標本身的空間。除非在定義的同時賦給指標一個字串常量進行初始化。例如:char *p = "breadrain"; 注意,只有字串常量才如此,不要指望為浮點數之類的常量分配空間:float *pip=3.14; 此語句錯誤,無法通過編譯。(在ANSI C中,初始化指標時建立的字串常量被定義為唯讀。如果試圖通過指標修改這個字串程式會出現未定義的行為)。數組也可以用字串常量初始化,並且可以修改:char a[] = “breadrain“; 字元指標和字元數組,分別可以通過指標名、數組名直接列印輸出。
什麼時候相同?
1. 運算式中的數組名被編譯器當做一個指向該數組第一個元素的指標。
2. 在函數參數的聲明中,數組名被編譯器當做指向該數組第一個元素的指標。
你要記住,在運算式中,指標和數組是可以互換的,因為它們在編譯器裡的最終形式都是指標,並且都可以進行取下標操作。因為數組的下標操作是建立在指標的基礎上的。所有在函數調用時候傳遞給被調用函數的數組,在編譯的時都被編譯器改寫為指標,即使被調用函數的型參聲明為數組。當想把數組定義為函數的參數時,可以把它定義為數組,也可以定義為指標。不管選擇那種方法,在函數的內部事實上獲得的是一個指標!
課後練習(如果你預測的結果正確,說明你真正理解了C語言中的數組和指標):
代碼
1 #include <stdio.h>
2
3 char ga[] = "abcdefghi";
4
5 void my_array_func(char ca[10])
6 {
7 printf("sizeof array param = %#x \n", sizeof ca);
8 printf("addr of array param = %#x \n", &ca);
9 printf("addr of (ca[0]) = %#x \n", &(ca[0]));
10 printf("addr of (ca[1]) = %#x \n", &(ca[1]));
11 printf("++ca = %#x \n\n", ++ca);
12 }
13
14 void my_pointer_func(char *pa)
15 {
16 printf("sizeof ptr param = %#x \n", sizeof pa);
17 printf("addr of ptr param = %#x \n", &pa);
18 printf("addr of (pa[0]) = %#x \n", &(pa[0]));
19 printf("addr of (pa[1]) = %#x \n", &(pa[1]));
20 printf("++pa = %#x \n\n", ++pa);
21 }
22
23 int main()
24 {
25 printf("sizeof global array = %#x \n", sizeof ga);
26 printf("addr of global array = %#x \n", &ga);
27 printf("addr of (ga[0]) = %#x \n", &(ga[0]));
28 printf("addr of (ga[1]) = %#x \n\n", &(ga[1]));
29 my_array_func(ga);
30 my_pointer_func(ga);
31 }
輸出:
輸出
sizeof global array = 0xa
addr of global array = 0x804a018
addr of (ga[0]) = 0x804a018
addr of (ga[1]) = 0x804a019
sizeof array param = 0x4
addr of array param = 0xbfd4ea50
addr of (ca[0]) = 0x804a018
addr of (ca[1]) = 0x804a019
++ca = 0x804a019
sizeof ptr param = 0x4
addr of ptr param = 0xbfd4ea50
addr of (pa[0]) = 0x804a018
addr of (pa[1]) = 0x804a019
++pa = 0x804a019
大功告成~~