读书人

C专家编程207页编程挑战的有关问题

发布时间: 2012-08-26 16:48:05 作者: rapoo

C专家编程207页编程挑战的问题
写了如下程序:

C/C++ code
   #include <stdio.h>       void func(char ca[]){        printf("%p %p %p\n", &ca, &(ca[0]), &(ca[1]));   }      void func2(char *pa){        printf("%p %p %p\n", &pa, &(pa[0]), &(pa[1]));   }     char abc[3] = {'A','B','C'};     int main(){       func(abc);       func2(abc);       return 0;   }  

执行后输出:
0x22ac50 0x402000 0x402001
0x22ac50 0x402000 0x402001

这个跟我想的一样。



但是函数func2(char *pa)的输出加上“++pa”后的程序如下:
C/C++ code
 #include <stdio.h>   void func(char ca[]){      printf("%p %p %p\n", &ca, &(ca[0]), &(ca[1])); }  void func2(char *pa){      printf("%p %p %p %p\n", &pa, &(pa[0]), &(pa[1]), ++pa); } char abc[3] = {'A','B','C'}; int main(){     func(abc);     func2(abc);     return 0; }


但是编译执行的输出结果是:
zhengxiaoxu@zhengxiaoxu-PC ~
$ ./test
0x22ac50 0x402000 0x402001
0x22ac50 0x402001 0x402002 0x402001

红色字体部分为什么不是0x402000 0x402001 和 0x402001??
为什么&(pa[0])的输出值被改变了?


求大神讲解下? 难道是编译器的问题嘛? 我搜过其他人的程序代码,他们加上“++pa”不会影响&(pa[0])的输出。

[解决办法]
关于这个问题我是这样理解的:
<code>
printf("%p %p %p %p\n", &pa, &(pa[0]), &(pa[1]), ++pa);
</code>
等效于
<code>
++pa;
printf("%p %p %p %p\n", &pa, &(pa[0]), &(pa[1]), pa);
</code>
[解决办法]
涉及序列点的问题。好像C标准只规定参数表达式求值前后和函数求值前后是序列点,但没有具体规定参数表达式之间的求值顺序。加了点代码,来看看:
C/C++ code
#include <stdio.h>#define CHECK(a)  check(#a,a)char* check(char*name, char* p){    printf("checking %s --> %p\n", name, p);    return p;}void func(char ca[]){    printf("%p %p %p\n", &ca, &(ca[0]), &(ca[1]));}void func2(char *pa){    printf("%p %p %p %p\n", &pa, CHECK(&(pa[0])), CHECK(&(pa[1])), CHECK(++pa));}char abc[3] = {'A','B','C'};int main(){    func(abc);    func2(abc);    return 0;}
[解决办法]
pa是个指针变量,&pa是变量pa自身的地址 0x22ac50;

pa是变量pa中保存的值,这个值才是数组abc的地址 0x402000。


C/C++ code
printf(&pa, &(pa[0]), &(pa[1]), ++pa) 

读书人网 >C语言

热点推荐