指針和數組有沒有關系呢?到底有什么關系,今天我們就來好好的看一看。
指針就是指針,指針變量在32位系統下,永遠占4字節,其值為某一個內存的地址。指針可以指向任何地方,但是不是任何地方你都能通過這個指針變量訪問到呢?
數組就是數組,其大小與元素的類型和個數有關;定義數組時必須指定其元素的類型和個數;數組可以存任何類型的數據,但不能存函數。
既然它們之間沒有任何關系,那為何很多人經常把數組和指針混淆,甚至很多人認為指針和數組是一樣的呢?我們先來看下吧。
1、以指針的形式訪問和以下標的形式訪問
下面我們就詳細討論討論它們之間似是而非的一些特點。例如,函數內部有如下定義:
(A)char *p = “abcdef”;
(B)char a[ ] = “abcdef”;
①以指針的形式訪問指針和以下標的形式訪問指針
以指針的形式:*(p+4)
以下標的形式:p[4]
這里的4 是偏移量,都是先取出p里存儲的地址值,加上偏移量,計算出新的地址,然后從新的地址中取出值。那么上面形式不同,訪問的本質是一樣的。
②以指針的形式訪問數組和以下標的形式訪問數組
以指針形式:*(a+4)
以下標形式:a[4]
我們都知道數組名代表數組首元素的首地址,加上4個元素的偏移量,得到新的地址,然后取出新地址上的值。
由此得出指針和數組都是可以“以指針的形式”或“以下標的形式”進行訪問,但是是完全不一樣的東西。
還有需要注意的是這個偏移量代表的是元素,而不是字節,偏移元素的個數再計算新的地址取值。
2、a 和 &a 的區別
先來舉個例子:
int a[5] = {1,2,3,4,5},b,c;
int *prt = (int *)(&a + 1);
b = *(a+1);
c = *(ptr-1);
對指針進行加1操作,得到的是下一個元素的地址,而不是原有地址值直接加1,所以一個類型為T的指針的移動,以sizeof(T)為移動單位。因此,對上面例子來說,a是一個一維數組,數組中有5個元素,所以&a+1是取數組a的首地址,該地址的值加上sizeof(a)的值,也就是&a+5*sizeof(int),也就是下一個數組的首地址,顯然當前指針已經越過了數組的界限。
那么*(a+1):a和&a的值是一樣的,但是意思不一樣,a是數組首元素的地址,也就是a[0]的首地址,&a是數組的首地址,a+1是數組下一個元素的首地址,也就是a[1]的首地址,&a+1是下一個數組的首地址,所以b的值應該是輸出2,*(ptr-1),因為前面我們分析ptr是指向a[5]的,并且ptr是int*類型,所以*(ptr-1)是指向a[4],輸出為5。
由此我們可以得知數組名a代表的是數組首元素的首地址,而不是數組的首地址,&a才是整個數組的首地址。
指針和數組你能完全理清楚了嗎?