Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46592
  • 博文数量: 35
  • 博客积分: 491
  • 博客等级: 下士
  • 技术积分: 285
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-12 15:37
文章分类

全部博文(35)

文章存档

2012年(8)

2011年(27)

我的朋友
最近访客

分类:

2011-10-18 20:30:51

本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
    

上次通过对比数组和指针,来研究数组和指针的本质,《编写安全代码:数组和指针的本质以及何时不能互换》。今天继续讨论数组的地址的本质,见下面的例子:
  1. #include <stdio.h>
  2. #include <stdlib.h>


  3. int main() {
  4.     int a[2][3];

  5.     printf("&a[0][0] address is 0x%X\n", &a[0][0]);
  6.     printf("&a[0]0]+1 address is 0x%X\n", &a[0][0]+1);
  7.     printf("size of pointer step is 0x%X\n", sizeof(*(&a[0][0])));
  8.     printf("\n");

  9.     printf("&a[0] address is 0x%X\n", &a[0]);
  10.     printf("&a[0]+1 address is 0x%X\n", &a[0]+1);
  11.     printf("size of pointer step is 0x%X\n", sizeof(*(&a[0])));
  12.     printf("\n");

  13.     printf("a address is 0x%X\n", a);
  14.     printf("a+1 address is 0x%X\n", a+1);
  15.     printf("size of pointer step is 0x%X\n", sizeof(*a));
  16.     printf("\n");

  17.     printf("&a address is 0x%X\n", &a);
  18.     printf("&a+1 address is 0x%X\n", &a+1);
  19.     printf("size of pointer step is 0x%X\n", sizeof(*(&a)));
  20.     printf("\n");

  21.     return 0;
  22. }
现在大家可以先想想输出是什么?
  1. [root@Lnx99 test]#./a.out
  2. &a[0][0] address is 0xBFF676F8
  3. &a[0]0]+1 address is 0xBFF676FC
  4. size of pointer step is 0x4

  5. &a[0] address is 0xBFF676F8
  6. &a[0]+1 address is 0xBFF67704
  7. size of pointer step is 0xC

  8. a address is 0xBFF676F8
  9. a+1 address is 0xBFF67704
  10. size of pointer step is 0xC

  11. &a address is 0xBFF676F8
  12. &a+1 address is 0xBFF67710
  13. size of pointer step is 0x18
从上面的输出,可以发现首地址都一样,但是让首地址的指针步进1次以后的地址却不一样。造成这样的结果是因为首地址指针的类型不同。

&a[0][0]的指针类型为int *p,所以步长为4;
&a[0]的指针类型为int (*p) [3],所以步长为12;
a的指针类型为int (*p) [3],所以步长仍然为12;
&a的指针类型为int (*p) [2][3],所以步长为24;


所以对于数组来说,无论是&a[0][0], &a[0], a还是&a,它们的地址都相同,但是由于其类型不同,所以并不是任何时候都可以互换的。

当使用数组的首地址时,一定要理解所使用首地址的类型,从而避免Bug。
阅读(498) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~