#include <stdio.h> int main(int argc, const char *argv[]) { int a[2][3] = { {1, 2, 3}, {4, 5, 6} }; printf("%p\n", a); printf("%p\n", *a); return 0; }
打印的结果是,一样的指针.
a究竟是怎么存储的,怎么会出现a和*a是一样的呢?
int a[10]
这里的数组其实是个指针,a就是指向第一个元素,如果那个元素是一个数组的话(多维数组),也就是说a指向一个指针
一个数组类型的变量,所占空间也就是数组中元素所占的空间,没有其它占用。
关键的两点是 C 语言规定:
- 除了作为 sizeof 和单目 & 操作符的操作数时,表达式中的数组均转化为指向数组首元素的指针。(也就是常说的:退化)
- 操作符
[]
是语法糖,使得a[n]
等价于*(a + n)
套用到你的代码里:
a
是int [2][3]
类型数组,单独出现在表达式中,转化为int (*)[2][3]
类型,指向数组a
的首地址。*a
是int [3]
类型数组,单独出现在表达式中,转化为int (*)[3]
类型,指向数组*a
的首地址。
前面也有说到 *a
其实和 a[0]
等价的,所以 *a
就是第一个子数组,所以其首地址和整个数组的地址是相同。
int a[1][2][3] = {
1, 2, 3,
4, 5, 6
};
printf("%p\n", a);
printf("%p\n", *a);
printf("%p\n", **a);
printf("%d\n", ***a);
return 0;
其中a,*a,**a都是一样的. 最后一行打印的是1
写了一个文章来理解这个问题 : http://hit9.github.io/oldblog/blog/C/posts/24.html
cut the crap,看图:
http://instagram.com/p/RJpP5puqv0
之前看的一篇文章:Learning C using GDB,你可以看看 https://www.hackerschool.com/blog/5-l...
#include<stdio.h> int main(){ int a[] = {1,2,3}; printf("a[0]=%d\n", a[0]); printf("*(a+0)=%d\n", *(a+0)); printf("a[1]=%d\n", a[1]); printf("*(a+1)=%d\n", *(a+1)); return 0; }
array的index access在C里只是对指针操作的一个语法糖。a[n]
完全等价于*(a+n)
回到你的问题。
- C语言里
int a[10]
的话,a
是一个指针指向a[0]
的指针 - C语言里
int a[2][3]
的话,a[0]
是一个指向a[0][0]
的指针,a[1]
是一个指向a[1][0]
的指针
在你的代码里,int a[2][3]
*a
指向a[0][0]
这个inta
指向a[0] = {1, 2, 3}
这个array。只不过在C里面,array的地址就是array第一个元素的地址,所以在这里a = a[0] = a[0][0]
a
是*int[3]
的指针,对其进行+1操作,内存指针往后移动sizeof(int[3])
个位置*a
是int
指针,对其进行+1操作,内存指针往后移动sizeof(int)
个位置
你可以运行下面代码测试下
#include<stdio.h> int main(){ int a[2][3] = { {1, 2, 3}, {4, 5, 6} }; printf("%p\n", a); printf("%p\n", a+1); printf("%p\n", (*a+1)); return 0; }