C中指针和变量之间的差异?
#include int inc1(int x) { return x++; } int inc2(int *x) { return (*x)++; } int main(void) { int a; a = 3; printf("%d\n", inc1(a) + a); printf("%d\n", inc2(a) + a); return 0; }
我正在处理一篇过去的论文,其中一个问题是跟踪第6行和第9行之间的变化。我有点理解指针(引用内存位置),但是如果有人可以直接告诉我对整个这段代码都很棒。
我将解释这个几乎相同的代码,它不包含你post中的错误:
#include int inc1(int x) { return x++; } int inc2(int *x) { return (*x)++; } int main(void) { int a; a = 3; printf("%d\n", inc1(a) + a); printf("%d\n", inc2(&a) + a); return 0; }
a
初始化为3,然后将a的值传递给inc1()
,返回它并使用post-increment加1 。 这意味着返回的实际值仍为3。
接下来, 将a的地址传递给inc2()
。 这意味着x中的值发生了什么。 同样,使用后增量,因此inc2()
返回的是3,但是在调用之后, a
是4。
但是,编译器可以按顺序点之间的任何顺序自由地计算表达式,例如a
或inc2(&a)
。 这意味着inc2(&a) + a
右侧的inc2(&a) + a
可以是3或4(取决于是否在int2(&a)
之前或之后评估int2(&a)
,因此程序可以输出6 7或6 6 。
调用inc1()的行将打印’6’(3 + 3)[前3是来自inc1(),由于后增量运算符,不返回增量值]。 此外,由于inc1()被值调用,因此’a’的值不会影响函数外部。
现在,如果论文中调用inc2()的声明如下:
printf("%d\n", inc2(a) + a);
然后你的代码将编译(希望你将存储位置存储在’a’中)但是在运行时取决于其中的值(在’a = 3’的情况下)你会得到Segmentation Fault,因为你试图取消引用内存位置3,不应该由您的程序访问。
或者,如果声明如下:
printf("%d\n", inc2(&a) + a);
然后inc2()将通过指针(地址)递增’a’的值,但由于其使用后增量运算符仍将返回’a’(3)的旧值,但它仍然会增加’a’以及任何后续访问’a’将获得新的价值。 下一个’a’将具有值’4’,因为评估是从左到右完成的,因此它将打印7(3 + 4)。
我希望它澄清了C中指针和变量之间的区别。