指针和数组(补充)
关于指针地址和数组首地址的关系总感觉没有说清,所以今天有对其进行了一下补充;
#include#include #include void main() { int a[3][3] = {{12,23,34},{21,45,554},{45,65,76}};//定义一个二维数组 相当于分成了三层,每层分配了三个int型变量 共36个字节 int (*b)[3];//数组指针是一个指向数组的二级指针(本质是一个指针)指针b分配了 4 个字节的空间 int *c[3];//指针数组 每个地址上装的是指针 分配了12个字节空间,一个指针是4个字节,则3个指针分配12个字节 b = a;//将数组的地址赋给b printf("sizeof(a)%d sizeof(b):%d sizeof(c):%d\n",sizeof(a),sizeof(b),sizeof(c));//36 4 12 printf("%d\n",sizeof(a[0]));//12 a[0] 代表着a[0][0] a[0][1] a[0][2] 三个变量的空间 所以是12个字节 printf("%d\n",sizeof(a[0][0]));//4 代表一个变量 printf(" %d %d %d %d \n",&a,a,a[0],a[0][0]);//&a是去a的地址,a代表的是a的首地址它和a的地址一样,a[0]是第一层的首地址,a[0][0]是从第一层的首地址里取值 printf("%d %d\n",a[1],a[1][0]);//a[1] 是第二层的首地址 a[1][0]是从第二层的首地址中取出值 printf("%d %d %d %d\n",&b,b,b[0],b[0][0]);//&b是取b的地址,b是指针指向的地址,b[0]取出/修改 指针指向的地址,b[0][0]读取/修改 b[0]空间上的值 system("pause"); }
当中我们可以看到数组的地址和数组的首地址是一样的(不要问它们为什么一样,这个得问编写编译器的大佬们了):不过说说我的看法好了,这就好比下面这样:
1 void main() 2 { 3 int a; 4 int *b; 5 a = 1;//我们可以这样修改 a 的数值 6 printf("%d\n",a); 7 scanf("%d",&a);//可以通过自己输入 8 printf("%d\n",a); 9 b = &a; 10 *b = 10;//还可以通过指针改 11 printf("%d\n",a); 12 scanf("%d",b);//通过指针的输入 13 printf("%d\n",a); 14 system("pause"); 15 16 }
然后我们可以发现其实取地址就是通过指针来修改内存空间,说白了我们就是通过地址来操作我们的内存空间的,要是想问数组地址和元素首地址为什么一样,就好像是问为什么 通过变量可以直接修改数值,而取地址也可以修改数值一样,其实仔细想想它们差不多的(如果操作的空间都不一样我们岂不是白操作了么!),当然他们是有不同的,a和a[0]是不一样的,a代表的是整个数组36个字节,a[0]代表第一层的三个变量的空间大小 12字节,而a[0][0]则代表第一层第一个元素的所以只有4个字节;
而指针的地址和指针所指向的地址是不一样的;而所有的指针都只占4个字节的空间(不论是几级指针,定义是这样的),且指针的空间只能储存地址而不能储存值,所以指针的地址和指针所指向的地址是不一样的的,它的内存空间上取出来的只能是地址,不能是数值;