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)