C中指针和变量之间的差异?

时间:2012-05-06 15:47:32

标签: c pointers

#include <stdio.h>
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行之间的变化。我有点理解指针(引用内存位置)但是如果有人可以通过对这段代码所做的更改很棒。

2 个答案:

答案 0 :(得分:3)

我将解释这个几乎完全没有错误的代码:

#include <stdio.h>

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,然后的值传递给inc1(),后者返回它并使用后增量。这意味着返回的实际值仍为3.

接下来,的地址传递给inc2()。这意味着x中的值发生了什么。同样,使用了后增量,因此inc2()返回的是3,但在调用之后,a为4。

但是,编译器可以按序列点之间的任意顺序自由评估表达式,例如ainc2(&a)。这意味着a右侧的inc2(&a) + a可能是3或4(取决于a之前或之后是否评估int2(&a),因此程序可能会输出 6 7 6 6

答案 1 :(得分:0)

调用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中指针和变量之间的区别。