C语言二位数组的深入理解
2012-05-16 19:08
302 查看
先上一段C语言代码:
{1,2,3}
{4,5,6}
{7,8,9}
来存放的,和以为和excel的表格一样;其实不然(我也看了C专家编程的C陷阱与缺陷两本书)。
1,2,3,4,5,6,7,8,9这个元素是以连续的地址存放的,下面的的形式可能更好理解:
...1,2,3|4,5,6|7,8,9...
数组cal[3]里有3个元素,每一个元素又是由3个整形元素构成的数组。
在这里,数组名cal是一个常量,我们是不能对其赋值的,他的值为首元素1的地址,而&cal是整个数组的地址,其值和cal相等,即&cal=cal但意义却不同,对其进行相应的运算所得到的结果大不一样:
cal+i=&cal[i];
&cal+i却不等于cal[i]
cal+i(i=0,1,2)为:
0x402000
0x40200c
0x402018
&cal+i(i=0,1,2)为:
0x402000
0x402024
0x402048
各位要注意:整个数组的大小为:3*3*4(sizeof(int))=36(十六进制为:0x00-0x23(咦!~~不是0x24(⊙o⊙)哦)),&cal+1的值为0x402024,&cal+1的值为0x402048,说明这时候(i=1、2)的操作已经超出了我们所定义的数组范围了。而且每一个都是一个和cal数组一样大的数组,只是他们的值是未定义的。
但是*(cal+i)的各个值为什么和前面几个的是一样呢?我也嘀咕着呢。。
我看着其实*(cal+i)=cal[i],因为cal+i=&cal[i];所以两边分别加*(解引用)号,得:
*(cal+i)=*&cal[i];--> *(cal+i)=cal[i];也就是为了后面的*(*(cal+j)+i)做铺垫的。
next就是&cal[j]+i的来源了:
&cal[j]+i:
j=0
0x402000 i=0
0x40200c i=2
0x402018 i=3
j=1
0x40200c i=0
0x402018 i=2
0x402024 i=3
j=2
0x402018 i=0
0x402024 i=2
0x402030 i=3
上面的(i和j调换了一下,不过不妨碍理解的)
&cal[j]和cal[j]有事不一样的,对其进行操作以后不同的结果。
1、&cal[j]+i就是在&cal[j]的地址基础上再加上i个拥有3个整型数组的大小的地址跨度,0就是不加,1就是加一个,以此类推。。。就会得到上面的结果了。
2、cal[j]+i就是在cal[j]的地址基础上再加上i个整型数组的大小的地址跨度,0就是不加,1就是加一个,以此类推。。。就会得到上面的结果了。
cal[j]+i:
j=0
0x402000 i=0
0x402004 i=2
0x402008 i=3
j=1
0x40200c i=0
0x402010 i=2
0x402014 i=3
j=2
0x402018 i=0
0x40201c i=2
0x402020 i=3
那么解引用*之后(即*(cal[j]+i)),得到:
11:
1 2 3
4 5 6
7 8 9
其实*(cal[j]+i) = *(*(cal+j)+i)的;而(cal[j]+i) = *(cal+j)+i。
完。。。
有些的不好的地方,大家多多指教。。O(∩_∩)O哈哈~
#include <stdio.h> int cal[3][3]= { {1,2,3}, {4,5,6}, {7,8,9} }; int main() { int i=0; int j=0; int num = 0; //printf the values of cal[0] and cal[1] printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",cal[i]); printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",cal+i); printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",&cal[i]); printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",*(cal+i)); printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",&cal+i); printf("%d:\n",++num); for(i=0; i<3; i++) printf("0x%0x\n",&cal[0][i]); printf("%d:\n",++num); for(j=0; j<3; j++) for(i=0; i<3; i++) printf("0x%0x\n",*(cal+j)+i); printf("%d:\n",++num); for(j=0; j<3; j++) { for(i=0; i<3; i++) { printf("%d ",*(*(cal+j)+i)); } putchar('\n'); } printf("%d:\n",++num); for(j=0; j<3; j++) { for(i=0; i<3; i++) { printf("0x%0x\n",&cal[j]+i); } } printf("%d:\n",++num); for(j=0; j<3; j++) { for(i=0; i<3; i++) { printf("0x%0x\n",cal[j]+i); } } printf("%d:\n",++num); for(j=0; j<3; j++) { for(i=0; i<3; i++) { printf("%d ",*(cal[j]+i)); } putchar('\n'); } printf("%d:\n",++num); printf("0x%0x\n",&cal); printf("0x%0x\n",cal); printf("0x%0x\n",*cal); printf("0x%0x\n",**cal); return 0; }运行结果如下:
1: 0x402000 0x40200c 0x402018 2: 0x402000 0x40200c 0x402018 3: 0x402000 0x40200c 0x402018 4: 0x402000 0x40200c 0x402018 5: 0x402000 0x402024 0x402048 6: 0x402000 0x402004 0x402008 7: 0x402000 0x402004 0x402008 0x40200c 0x402010 0x402014 0x402018 0x40201c 0x402020 8: 1 2 3 4 5 6 7 8 9 9: 0x402000 0x40200c 0x402018 0x40200c 0x402018 0x402024 0x402018 0x402024 0x402030 10: 0x402000 0x402004 0x402008 0x40200c 0x402010 0x402014 0x402018 0x40201c 0x402020 11: 1 2 3 4 5 6 7 8 9 12: 0x402000 0x402000 0x402000 0x1数组的定义即初始化这里不说了,在C语言了多维数组是以“数组的数组”的形式来实现的,所以一开始我们有点迷糊,以为在内存里也是以
{1,2,3}
{4,5,6}
{7,8,9}
来存放的,和以为和excel的表格一样;其实不然(我也看了C专家编程的C陷阱与缺陷两本书)。
1,2,3,4,5,6,7,8,9这个元素是以连续的地址存放的,下面的的形式可能更好理解:
...1,2,3|4,5,6|7,8,9...
数组cal[3]里有3个元素,每一个元素又是由3个整形元素构成的数组。
在这里,数组名cal是一个常量,我们是不能对其赋值的,他的值为首元素1的地址,而&cal是整个数组的地址,其值和cal相等,即&cal=cal但意义却不同,对其进行相应的运算所得到的结果大不一样:
cal+i=&cal[i];
&cal+i却不等于cal[i]
cal+i(i=0,1,2)为:
0x402000
0x40200c
0x402018
&cal+i(i=0,1,2)为:
0x402000
0x402024
0x402048
各位要注意:整个数组的大小为:3*3*4(sizeof(int))=36(十六进制为:0x00-0x23(咦!~~不是0x24(⊙o⊙)哦)),&cal+1的值为0x402024,&cal+1的值为0x402048,说明这时候(i=1、2)的操作已经超出了我们所定义的数组范围了。而且每一个都是一个和cal数组一样大的数组,只是他们的值是未定义的。
但是*(cal+i)的各个值为什么和前面几个的是一样呢?我也嘀咕着呢。。
我看着其实*(cal+i)=cal[i],因为cal+i=&cal[i];所以两边分别加*(解引用)号,得:
*(cal+i)=*&cal[i];--> *(cal+i)=cal[i];也就是为了后面的*(*(cal+j)+i)做铺垫的。
next就是&cal[j]+i的来源了:
&cal[j]+i:
j=0
0x402000 i=0
0x40200c i=2
0x402018 i=3
j=1
0x40200c i=0
0x402018 i=2
0x402024 i=3
j=2
0x402018 i=0
0x402024 i=2
0x402030 i=3
上面的(i和j调换了一下,不过不妨碍理解的)
&cal[j]和cal[j]有事不一样的,对其进行操作以后不同的结果。
1、&cal[j]+i就是在&cal[j]的地址基础上再加上i个拥有3个整型数组的大小的地址跨度,0就是不加,1就是加一个,以此类推。。。就会得到上面的结果了。
2、cal[j]+i就是在cal[j]的地址基础上再加上i个整型数组的大小的地址跨度,0就是不加,1就是加一个,以此类推。。。就会得到上面的结果了。
cal[j]+i:
j=0
0x402000 i=0
0x402004 i=2
0x402008 i=3
j=1
0x40200c i=0
0x402010 i=2
0x402014 i=3
j=2
0x402018 i=0
0x40201c i=2
0x402020 i=3
那么解引用*之后(即*(cal[j]+i)),得到:
11:
1 2 3
4 5 6
7 8 9
其实*(cal[j]+i) = *(*(cal+j)+i)的;而(cal[j]+i) = *(cal+j)+i。
完。。。
有些的不好的地方,大家多多指教。。O(∩_∩)O哈哈~
相关文章推荐
- 深入理解c语言数组
- 深入理解C语言中的指针与数组之指针篇
- 深入理解C语言中的指针与数组之指针篇
- 【笔试面试知识点查缺补漏深入理解之C与C++篇】C语言中的指针数组与数组指针
- 深入理解C语言中的指针与数组之指针篇(转载)
- 深入理解C语言特性-指针 数组 声明
- C语言深入理解系列--数组
- 深入理解C语言中的指针与数组之指针篇
- ubantu 配置<<深入理解计算机系统>>的 C语言编程环境
- 深入理解C语言(包含oop的思想,内存和管理,I/O的实现)
- 【C语言天天练(十一)】深入理解指针
- 【项目经验】C语言中inline的深入理解
- 深入理解PHP之数组(遍历顺序) Laruence原创
- c语言深入理解<4>
- 数组的深入理解之p=&(b+1)[5]
- 基于C语言sprintf函数的深入理解
- 深入理解C语言指针的奥秘
- 【笔试面试知识点查缺补漏深入理解之C与C++篇】C语言中的引用
- C语言中值得深入知识点----数组做函数参数、数组名a与&a区别、数组名a的"数据类型"