数组和数组名取址的区别(转自windflush.cn/blog)

起因是Expert C Programming的一道习题:

  1. #include <stdio.h>
  2.  
  3. char ga[14] = "abcdefghijklm";
  4.  
  5. void my_array_func( char ca[10] )
  6. {
  7.    printf(" addr of array param = %#x /n",&ca);
  8.    printf(" addr (ca[0]) = %#x /n",&(ca[0]));
  9.    printf(" addr (ca[1]) = %#x /n",&(ca[1]));
  10.    printf(" ++ca = %#x /n/n", ++ca);
  11. }
  12. void my_pointer_func( char *pa )
  13. {
  14.    printf(" addr of ptr param = %#x /n",&pa);
  15.    printf(" addr (pa[0]) = %#x /n",&(pa[0]));
  16.    printf(" addr (pa[1]) = %#x /n",&(pa[1]));
  17.    printf(" ++pa = %#x /n", ++pa);
  18. }
  19.  
  20. int main(void)
  21. {
  22.    printf(" addr of global array = %#x /n",&ga);
  23.    printf(" addr (ga[0]) = %#x /n",&(ga[0]));
  24.    printf(" addr (ga[1]) = %#x /n/n",&(ga[1]));
  25.    my_array_func( ga );
  26.    my_pointer_func( ga );
  27.     return 0;
  28. }


输出如下:

addr of global array = 0×8049784
addr (ga[0]) = 0×8049784
addr (ga[1]) = 0×8049785

addr of array param = 0xbfc31bd0
addr (ca[0]) = 0×8049784
addr (ca[1]) = 0×8049785
++ca = 0×8049785

addr of ptr param = 0xbfc31bd0
addr (pa[0]) = 0×8049784
addr (pa[1]) = 0×8049785
++pa = 0×8049785

Expert C programming中这个题的主要用意是想让读者知道:
the address of an array parameter not equal to the address of the first element of the array parameter

当然,这个不是问题,不过下面这个代码却吸引了我的注意:

  1. printf(" addr of global array = %#x /n",&ga);

对数组名取地址!我以前从没想过这个行为,从代码的运行来看,显然是合法的行为。可是为什么会和ga的地址相同呢?原本以为,ga&ga应该和p&p一样,结果是不同的,可是我却错了,他们俨然相同!

既然&ga的地址和ga的相同,那么我将&ga的地址赋给指针试试吧:

  1. char *p = &ga;

可是结果却是:
警告: 从不兼容的指针类型初始化

经过查找,终于明白了其中的原因,下面的代码可以让你对这个结果的产生释疑:

  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.     char a[10]="djfkldfj";
  6.     printf("addr of a is:%#x, addr of a+1 is:%#x/n", a, a+1);
  7.     printf("addr of &a is:%#x, addr of &a+1 is:%#x/n", &a, &a+1);
  8.     return 0;
  9. }

输出为:

addr of a is:0xbfe3b5e6, addr of a+1 is:0xbfe3b5e7
addr of &a is:0xbfe3b5e6, addr of &a+1 is:0xbfe3b5f0

很明显可以看出:
&a+1的值是10,是字符数组a的大小!

实际上,对数组取char a[10]进行&a运算得到的是一个指向数组的指针char (*)[10],理所当然地,&a+1的结果是地址增长了10*sizeof(char)的大小了。也当然可以理解为什么上面的

  1. char *p = &ga;

出错了,而且出现的是 警告: 从不兼容的指针类型初始化

这明显是不同类型的指针,而且他们互不兼容,必然不行。
如果改成
char (*p)[14] = &ga;
就可以了。
注意:不要一时疏忽写成 char *p[14] = &ga;
原因你们必然都知道的。

经过这道习题,我算是对数组指针又加深了印象。不过不知道这块C99标准有什么规定没,我没有找到,应该是有的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值