C51程序設(shè)計中的數(shù)組和指針關(guān)系
一、指針是地址
各種類型的數(shù)據(jù)被分配合適的內(nèi)存。比如整形數(shù)據(jù)通常被分配兩個連續(xù)的存儲單元(字節(jié))存放。對數(shù)據(jù)的訪問是通過分配給數(shù)據(jù)的內(nèi)存首地址來實現(xiàn)的。我們稱這些內(nèi)存地址為指針。
二、指針變量是存放地址的變量
如果我們定義了一些變量來存放數(shù)據(jù)的地址(指針),這樣的變量就是指針變量。也就是說,指針變量有兩個特征:首先它作為變量會分配內(nèi)存空間;其次,它存放的內(nèi)容應(yīng)該是內(nèi)存地址。
比如,當(dāng)我們聲明了一個整形變量i并且賦予初始值10;同時我們聲明了一個整形的指針變量p,將它指向變量i。當(dāng)我們運行代碼時,內(nèi)存中可能是這樣的:
i -> |0AH| FFF0H
|00H|FFF1H
|...|
p -> |0F0H | FFFAH
|0FFH|FFFBH
三、一維數(shù)組是指針,它指向數(shù)組首(元素)地址
1. 代碼int a[3] = {1, 2, 3}; 定義了一個包含3個元素的整形一維數(shù)組。在引用數(shù)組元素時,我們使用“a[下標(biāo)]”的格式;在引用數(shù)組時,我們直接使用數(shù)組名a。而數(shù)組名a表示(指向)數(shù)組首元素的地址(指針)
測試代碼:
int a[3] = {1, 2, 3};
printf("a = %xn", a);
printf("&a[0] = %xn", &a[0]);
執(zhí)行結(jié)果:
a= fff0
&a[0] = fff0
2. 由于一維數(shù)組是指針,所以可以按照指針來操作它: 一維數(shù)組指向數(shù)組首元素,所以在一維數(shù)組前加一元操作符“*”可以返回第一個元素的值。比如:
測試代碼:
int a[3] = {1, 2, 3};
printf("*a = %xn", *a);
printf("a[0] = %xn", a[0]);
執(zhí)行結(jié)果:
*a= 1
a[0] = 1
四、一維數(shù)組(名)不是指針變量
上面的測試代碼中,數(shù)組名a是一個指針變量嗎? 如果數(shù)組名a是一個指針變量,那么,它在應(yīng)該會被分配獨立的存儲空間(有自己的地址),并且它的值應(yīng)該是數(shù)組首地址,如圖:
指針變量a -> | 0F0H | xxxxH
| 0FFH | yyyyH
...
元素a[0]-> |01H| FFF0H
|00H| FFF1H
|02H| FFF2H
|00H| FFF3H
|03H| FFF4H
|00H| FFF5H
下面,我們再做一個試驗:
int a[3] = {1, 2, 3};
printf("&a = %xn", &a);
printf("a= %xn", a);
printf("*a = %xn", *a);
printf("a[0] = %xn", a[0]);
執(zhí)行結(jié)果:
&a = fff0
a= fff0
*a = fff0
a[0] = 1
執(zhí)行結(jié)果很奇怪,如果按照結(jié)果畫出內(nèi)存示意圖,似乎是這樣的:
指針變量a -> | 0F0H |FFF0H
| 0FFH |FFF1H
...
元素a[0]-> |01H|FFF0H
|00H|FFF1H
|02H| FFF2H
|00H| FFF3H
|03H| FFF4H
|00H| FFF5H
奇怪在哪里? ------ 怎么可能有兩個內(nèi)存空間的地址相同呢(FFF0H)? 當(dāng)然不可能,這正好說明數(shù)組名a并不是一個指針變量因為它沒有自己的存貯空間。這些奇怪的結(jié)果是編譯器在編譯期間根據(jù)另外的規(guī)則做出的處理。