C語言規定,數組名代表數組的首地址,也就是第0號元素的地址。所以a==&a[0]
但對數組名取地址時卻要注意了,在理解“對數組名取地址”這一表達式的含義時一定要記住:數組名是“數組”這種變量的變量名
這樣,&a就好理解了,它取的是“數組”這種變量的地址
&a+1自然也就要跨過整個數組,所有元素長度總和,這么長的一個長度。例如:int a[10],那么&a+1就要跨過10個int的長度
詳細分析——
1 int array[100];
2
3 memset(array, 0, sizeof(array));
4 memset(&array, 0, sizeof(array));
第3行和第4行有什么不同嗎?其實從效果上來說是一樣的,但是這里要注意 array 和 &array 的類型是不同的。
array 相當於 &array[0],它們都是整型指針。而 &array 是一個指向 int[100] 的指針,這是一個數組指針,類型是 int(*)[100],當用數組指針變量來接收它的值時,你會發現它與整型指針array、&array[0]的巨大不同。
以下代碼可以看出這個不同:
#include <stdio.h>
int main()
{
int array[100] = {0, 1, 2};
typedef int (*ARRAY)[100];
int *p1 = array;//數組名代表第0號元素的地址(准確的說應該是代表第0號元素的指針):&array[0],第0號元素是一個整型變量
ARRAY p2 = &array;
int *p3 = &array;//實際上賦值符自動向下兼容,將&array轉換為了一個整型變量指針:&array[0]
//或者可能是像空指針可以接收所有類型的指針值一樣,各類型的指針都可以接收自己類型的數組指針,並完成兼容性轉換,例如int型指針可以接收int數組的數組指針,並轉換為int型指針;char型指針可以接收char數組的數組指針,並轉換為char型指針。
printf("p1 = 0x%08d\n", p1);
printf("p2 = 0x%08d\n", p2);
printf("p3 = 0x%08d\n", p3);
printf("int=%dbyte\n",sizeof(int));
printf("p1+1=0x%08d\n",p1+1);
printf("p2+1=0x%08d\n",p2+1);
printf("p3+1=0x%08d\n",p3+1);
printf("p1[2] = %d\n", p1[2]);
printf("p2[2] = %d\n", p2[2]);
printf("p3[2] = %d\n", p3[2]);
printf("(*p2)[2] = %d\n", (*p2)[2]);
//printf("(*p1)[2] = %d\n", (*p1)[2]);//這樣編譯錯誤
//printf("(*p3)[2] = %d\n", (*p3)[2]);//這樣編譯錯誤
getchar();
return 0;
}
運行結果可能是:
從上面的分析以及程序可以發現:
指針與地址其實還是有差異的,指針的屬性中包含有地址這個概念,而且對於不同的指針,其地址概念卻都是相同的,都是用一個數表示內存條上的某個位置。
但指針的屬性中還有大小、距離的概念:
大小——不同類型的指針,其指向的變量所占據的內存大小不同,即從內存條上的起始位置(即地址)開始,所占據的字節數不同。例如int占4個byte,char占1個byte
距離——不同類型的指針移動一個單位,其在內存條上移動的字節數不同。例如int型指針+1則移動4個byte,char型指針+1則移動1個byte,數組型指針+1則移動許多許多個byte