娓娓道来c指针 (5)c数组本质
来源:互联网 发布:文华财经交易模型源码 编辑:程序博客网 时间:2024/05/21 17:48
(5)c数组本质
c中的数组是一种聚合类型,把同种类型的元素按顺序存储,即是数组。c中数组类型的特点在于:它是嵌套定义的。
看下一个二维数组int array[2][3]={{1,2,3},{4,5,6}};的内存存储形式:
c中的数组是嵌套定义的:二维数组的元素是一维数组,三维数组的元素是二维数组……
像array[2][3]这样的二维数组,是由两个一维数组组成的:array[0]、array[1],这两个一维数组的规模都是array的第二个下标3。同时,array[0]、array[1]就是两个一维数组名。由于元素都是顺序存储的,故可以通过以下的方式挨个访问array中元素:
int main(void){int array[2][3] = {{ 1, 2, 3 },{ 4, 5, 6 }};//让p指向数组首元素int *p = &array[0][0];while (p < &array[1][3]){printf("%4d", *p);p++;}printf("\n\n");return 0;}运行
这种访问方式能够成功,关键就在于c中的多维数组本质是数组的数组,并且元素顺序存储。
在代码中出现了&array[1][3],是不是越界了呢?理论上array[1][2]是array的最后一个元素,array[1][3]正好是其下一个,这里我们取其地址,而不是访问元素,这是可以的。
下面来探讨一下这三个数组名:array、array[0]和array[1]是何种类型的指针。
首先,在(3)数组和指针中,我们提到过,对于数组int array[N];(N是一常量)。数组名array是一指向数组首元素的常量指针(也就是说,不可再指向别的存储单元),而&array是一指向整个数组的指针。这里以此类推:
- array[0]是指向array[0][0]的指针,类型是int *。&array[0]是指向数组的指针,类型是int(*)[3]。
- array[1]和array[0]类型相同,&array[1]和&array[0]的类型相同。当然,只是类型相同,值不同。
- array应是指向array[0]的指针,而array[0]是一个一维数组int[3],故array是一个指向一维数组的指针,类型是int(*)[3]。&array应是指向整个二维数组的指针,类型是int(*)[2][3]。
做实验验证:
编译下,无任何警告,我们的猜想正确。以上两个实验可以充分说明c数组的本质:数组的数组。
int main(void){int array[2][3] = {{1, 2, 3},{4, 5, 6}};int *pa = array[0];int (*pb)[3] = &array[0];int (*pc)[3] = array;int (*pd)[2][3] = &array;return 0;}
小测一下;
三维数组 int array[2][3][4]; array的类型?&array的类型?array[0]的类型?array[0][0]的类型?(答案在最后,先想想,再看答案。)
另一种测试,使用指针运算来验证
int main(void){int array[2][3] = {{1, 2, 3},{4, 5, 6}};int *pa = array[0];int (*pb)[3] = &array[0];int (*pc)[3] = array;int (*pd)[2][3] = &array;printf("array...%p\n", array);printf(" pa+1...%p\n", pa + 1);printf(" pb+1...%p\n", pb + 1);printf(" pc+1...%p\n", pc + 1);printf(" pd+1...%p\n", pd + 1);return 0;}运行
计算后四者和array的差值,结论即可得到。
总结
c数组的本质是:数组的数组。至于数组名 array 和 &array 的指针类型问题,只需记忆两点,其它可推理。这两点是:
- array指向数组首元素,弄清楚了元素类型是什么,指针类型自然就推出来了。
- &array被规定为指向整个数组,它的类型更简单。
测试答案
array的类型是int(*)[3][4];&array的类型是int(*)[2][3][4];array[0]的类型是int(*)[4];array[0][0]的类型是int*。
专栏目录:
- C指针
- 数据结构与算法
2 0
- 娓娓道来c指针 (5)c数组本质
- 娓娓道来c指针 (3)指针和数组
- 娓娓道来c指针 (3)指针和数组
- 娓娓道来c指针 (1)指针就是地址
- 娓娓道来c指针 (7)指针运算
- 娓娓道来c指针 (1)指针就是地址
- 娓娓道来c指针 (2)内存分配
- 娓娓道来c指针 (6)const的使用
- 娓娓道来c指针 (0)c语言的梦魇:c指针
- 娓娓道来c指针 (4)解析c的声明语句
- 娓娓道来c指针 (4)解析c的声明语句
- 娓娓道来c指针 (8)开发可变参数函数
- C指针本质
- c数组本质
- C语言指针和数组的本质区别
- C提高——数组、数组数据类型、数组数据类型指针、多维数组本质等
- 【C/C++】指针数组
- 【c/c++】指针数组和数组指针
- LeetCode OJ算法题(三十四):Search Insert Position
- cmd 模块构建,从认识grunt开始
- C3P0在Linux下的Failed to get local InetAddress for VMID解决方法
- java动态代理(JDK和cglib)
- Qt在Windows下的三种编程环境搭建
- 娓娓道来c指针 (5)c数组本质
- Cause: java.io.UTFDataFormatException: Invalid byte 3 of 3-byte UTF-8 sequence. 解决办法
- Activiti工作流简介
- NC(NetCat)命令详解
- HDU 3549 Flow Problem
- 64位的linux装的hadoop是32位的,需要手工编译
- hdu-1031-Design T-Shirt
- 蛋疼的ViewPager+竖直SeekBar实现过程(1)竖直SeekBar实现
- 斥巨资打造鹰目LED联播网