Adolph两边

 

关于数组的一些高级分析

今天为了描述这个问题,折腾了很久.下面就总结归纳一下.
首先数组名是不占空间的.
列:
int a[10];
printf("%d", a);
printf("%d", &a);
上面的输出是一样的.
而指针是占用空间的.
int b[10];
int *p;
p = b;
printf("%d", p);
printf("%d", &p);
上面的输出是不一样的.

下面开始重点部分:多维数组.
实际上我是不建议理解成多维数组的.内存都是线性的,仅此而已.大家可以看看下面这个例子.
int a[] = {1,2,3,4,5};
int b[][2] = {{1,2},{3,4},{5,6},{7,8}};
发现共同点了么?a的长度是根据定义的获得的.b同样也是.不过a的每个元素是一个int,而b的每个元素是一个数组.

多维数组还提供另外一个理解方式,如下:
int arr_1[4][10];

int a[10];
int b[10];
int c[10];
int d[10];
int *arr_2[4] = {a, b, c, d};  //指针数组
则:
arr_1 + 1 = arr_2 + 1    此时该指针是第一维度中的一个元素的地址
*(arr_1 + 1) = *(arr_2 + 1) = b  虽然做了解引用,但是取得的值依然是一个指针,不过维度就到达了第二维度,就是指向长度为10的数组的第一个元素
*(arr_1 + 1) +1 = b + 1   此时指针指向第二维中的第一个元素
*(*(arr_1 + 1) +1) = *(b + 1) = b[1] 这次就真正获得其中的一个值了.

虽然可以这么理解,但是依然要记住指针和数组是不一样的.

1.上面的2中表达方式,所需要的内存是不一样的.第一种为sizeof(int)X4X10,第二种为sizeof(int)X4X10 + sizeof(int *)X4.
2.例如你使用arr_1[1][11]这样的方式访问,可以依赖编译器检查出错误.而当你使用arr_2[1][11]这样的方式访问的时候,编译器将没有任何警告.可怕的内存泄露!

高级部分:
int array[4][10];
int **p;
p = array; //报错
int (*p1)[9];
p1 = array; //报错
int (*p2)[10];
*p2 = array; //正确
所以简单的说多维数组就是多级指针是有误的.从p2可以看出来,你必须正确匹配类型,这里是包含10个int元素的数组.这也就解释了为什么声明数组的时候只能省略第一维度.

参考书籍《C专家编程》

posted on 2011-12-02 15:14  Adolph两边  阅读(129)  评论(0编辑  收藏  举报

导航