起因是Expert C Programming的一道习题:
- #include <stdio.h>
- char ga[14] = "abcdefghijklm";
- void my_array_func( char ca[10] )
- {
- printf(" addr of array param = %#x /n",&ca);
- printf(" addr (ca[0]) = %#x /n",&(ca[0]));
- printf(" addr (ca[1]) = %#x /n",&(ca[1]));
- printf(" ++ca = %#x /n/n", ++ca);
- }
- void my_pointer_func( char *pa )
- {
- printf(" addr of ptr param = %#x /n",&pa);
- printf(" addr (pa[0]) = %#x /n",&(pa[0]));
- printf(" addr (pa[1]) = %#x /n",&(pa[1]));
- printf(" ++pa = %#x /n", ++pa);
- }
- int main(void)
- {
- printf(" addr of global array = %#x /n",&ga);
- printf(" addr (ga[0]) = %#x /n",&(ga[0]));
- printf(" addr (ga[1]) = %#x /n/n",&(ga[1]));
- my_array_func( ga );
- my_pointer_func( ga );
- return 0;
- }
输出如下:
addr of global array = 0×8049784
addr (ga[0]) = 0×8049784
addr (ga[1]) = 0×8049785addr of array param = 0xbfc31bd0
addr (ca[0]) = 0×8049784
addr (ca[1]) = 0×8049785
++ca = 0×8049785addr 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
当然,这个不是问题,不过下面这个代码却吸引了我的注意:
- printf(" addr of global array = %#x /n",&ga);
对数组名取地址!我以前从没想过这个行为,从代码的运行来看,显然是合法的行为。可是为什么会和ga的地址相同呢?原本以为,ga和&ga应该和p和&p一样,结果是不同的,可是我却错了,他们俨然相同!
既然&ga的地址和ga的相同,那么我将&ga的地址赋给指针试试吧:
- char *p = &ga;
可是结果却是:
警告: 从不兼容的指针类型初始化
经过查找,终于明白了其中的原因,下面的代码可以让你对这个结果的产生释疑:
- #include <stdio.h>
- int main(void)
- {
- char a[10]="djfkldfj";
- printf("addr of a is:%#x, addr of a+1 is:%#x/n", a, a+1);
- printf("addr of &a is:%#x, addr of &a+1 is:%#x/n", &a, &a+1);
- return 0;
- }
输出为:
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)的大小了。也当然可以理解为什么上面的
- char *p = &ga;
出错了,而且出现的是 警告: 从不兼容的指针类型初始化
这明显是不同类型的指针,而且他们互不兼容,必然不行。
如果改成
char (*p)[14] = &ga;
就可以了。
注意:不要一时疏忽写成 char *p[14] = &ga;
原因你们必然都知道的。
经过这道习题,我算是对数组指针又加深了印象。不过不知道这块C99标准有什么规定没,我没有找到,应该是有的。