1
#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 行之间对 a 所做的更改。我有点理解指针(引用内存位置),但如果有人可以告诉我所做的更改整个这段代码都很棒。

4

2 回答 2

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,然后将 a 的值传递给inc1(),它返回它并使用post-increment 加1 。这意味着返回的实际值仍然是 3。

接下来,将 a 的地址传递给inc2()。这意味着 x 中的值发生的事情发生在 a 上。同样,使用了后增量,所以inc2()返回的是 3,但在调用之后a是 4。

但是,编译器可以自由地在序列点之间以任何顺序评估表达式,例如aor 。这意味着右边的可能是 3 或 4 (取决于是在 之前还是之后评估,因此程序可能输出6 76 6inc2(&a)ainc2(&a) + aaint2(&a)

于 2012-05-06T15:59:02.920 回答
0

调用 inc1() 的行将打印 '6' (3+3) [前 3 个来自 inc1(),由于后增量运算符,不返回增量值]。此外,由于 inc1() 是按值调用的,因此“a”的值在函数外部不受影响。

现在,如果论文中调用inc2()的语句如下:

printf("%d\n", inc2(a) + a);

然后您的代码将编译(希望您将内存位置存储在“a”中)但取决于其中的值(如果“a = 3”)在运行时您将得到分段错误,因为您试图取消引用程序不应访问的内存位置 3。

或者,如果语句如下:

printf("%d\n", inc2(&a) + a);

然后 inc2() 将通过指针(地址)增加 'a' 的值,但仍将返回 'a' (3) 的旧值,因为它使用了后递增运算符,但无论如何它都会增加 'a' 和任何后续访问to 'a' 将获得新值。下一个“a”将具有值“4”,因为评估是从左到右进行的,因此它将打印 7 (3+4)。

我希望它能阐明 C 中指针和变量之间的区别。

于 2012-05-11T16:51:56.007 回答