数组与指针间的三条规则:
数组名是指向数组首元素的指针。
&E相当于给E升了一阶。(int a[4]={1,2,3,4},a[0]本身是一个值,&a[0]是一个地址,升阶大概就是这个意思)
*E相当于给E降了一阶。(降阶相当于把一个指针降为值,&a[0]是一个地址,*(&a[0])就成为了值)
以上内容来自北京大学 c程序设计进阶
一维数组与指针
1 #include<stdio.h>
2 #include<stdlib.h>
3 int main()
4 {
5 int a[4]={1,2,3,4};
6 printf("%p
",a); //数组首元素的地址
7 printf("%p
",&a[0]);//数组首元素的地址,a[0]为值,加&升阶
8 printf("%p
",a+1);//a为数组首元素的地址,数组首元素为指向int型的指针,a+1为第二个元素的地址
9 printf("%p
",&a[0]+1);//a[0]为数组的首元素,加&升阶,再加一为第二个元素的地址
10 printf("%p
",&a);//a为数组 首元素的地址,&a升阶,为指向数组的指针,值还是和数组首元素的地址一样,意义不同。
11 printf("%p
",&a+1);//&a为指向数组的指针,数组有4个元素,+1则一次加16个字节,
12 printf("%p
",*(&a+1));//加*降阶,为指向数组最后一个元素后面的地址,还是地址
13 printf("%p
",*(&a));//加*降阶,为指向数组首元素的指针,值为数组首元素的地址
14 printf("%d
",**(&a+1));//再加一个*再次降阶,为一个垃圾值
15 printf("%d
",**(&a));//为数组首元素的值
16 printf("%d
",*(&a[0]));//同上
17 exit(0);
18
19 }
运行结果如上。
二维数组与指针
一个二维数组int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
在内存中存放的时候是按照顺序存放的,关于二维数组与指针的关系,依然可以套用上面的三条规则,这时的a还是数组首元素的指针,只不过这个首元素是一个一维数组。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("a=%p
",a);//数组首元素的指针,和1的地址相同
printf("&a[0]=%p
",&a[0]);//a[0]是二维数组首元素的指针,二维数组首元素是一个一维数组,加&升阶后和上面的意义一样
printf("a+1=%p
",a+1);//二维数组的第二个元素的地址
printf("&a[0]+1=%p
",&a[0]+1);//
printf("a[1]=%p
",a[1]);
printf("&a[1]=%p
",&a[1]);
printf("*(a+1)=%p
",*(a+1));//a+1是二维数组的第二个元素的地址,加*降阶为第二个元素的首元素的地址
printf("*a+1=%p
",*a+1);//a是二维数组首元素的地址加*降阶,为第一个元素的首元素的地址,+1为二维数组第一个元素的第二个元素的地址
printf("&a=%p
",&a);//指向整个二维数组的指针
printf("&a+1=%p
",&a+1);//+1一次跨越48个字节
exit(0);
}
运行结果如下