”尽管术语上称作‘多维数组’,但C语言实际上只支持‘数组的数组’。“(《C专家编程》第二版211页)
”在C语言中,可以像下面这样声明一个10×20的多维字符数组
char carrot[10][20];
或者声明一种看上去更像‘数组的数组’形式:
typedef char vegetable[20];
vegetable carrot[10];
不论哪种情况,访问单个字符都是通过carrot[i][j]的形式,
编译器在编译时会把它解析为*(*(carrot+i)+j)的形式。“
除了初始化之外,数组不可以被直接整体赋值
数组的初始化
使用花括号初始化数组
int arr0[5]={1,2,3,4,5};
int arr2[2][3]={{0,1,2}, {10,11,12)};
char s[10]="abcd";
char s2[2][10]={"abcd", "2222"};
初始化时,最后维度大小可省略,由编译器自动生成
int arr0[]={1,2,3,4,5};
int arr2[][3]={{0,1,2}, {10,11,12)};
char s[]="abcd";
char s2[][10]={"abcd", "2222"};
给定维度大小,若初始化数据不足,则自动补零(0, 0.0f, 0L, NULL...)
int arr0[5]={1}; //相当于int arr0[5]={1,0,0,0,0};
int arr2[][3]={{0,1,2}, {10)}; //相当于int arr2[2][3]={{0,1,2}, {10,0,0)};
数组指针
给一个数组赋值,需要取消最左的维度,例如
int a[3];
int (*pa); //pa指向int。等同于int *pa;
pa=a;
int arr[2][3];
int (*parr)[3]; //parr指向int[3]
parr=arr;
之所以要保留部分维度,是为了知道数组元素的size,以保证指针地址运算的正确性:
sizeof(*pa)=sizeof(int),所以 pa+1指向pa之后4个字节的位置
sizeof(*parr)=sizeof(int[3]),所以 parr+1指向parr之后12个字节的位置
至于数组指针指向的数组是直接定义也罢,new出来的也好,都是一样的。
由上可知,数组指针实际上指向的是N维数组中“N-1维的数组元素”,所以它需要知道数组元素的维度信息。
这也比较容易理解:数组指针是用来存取数组元素的嘛。
参考资料:
1、C++中int *p[4]和 int (*q)[4]的区别 http://blog.youkuaiyun.com/ajioy/article/details/6951643
2、数组与指针概念剖析 http://blog.youkuaiyun.com/code_crash/article/details/4855027