指针和数组(补充)


  关于指针地址和数组首地址的关系总感觉没有说清,所以今天有对其进行了一下补充; 

#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个字节的空间(不论是几级指针,定义是这样的),且指针的空间只能储存地址而不能储存值,所以指针的地址和指针所指向的地址是不一样的的,它的内存空间上取出来的只能是地址,不能是数值;