2012-05-06 40 views
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行之间所做的更改。我理解指针(指向内存位置),但如果有人可以跟我说话通过对整个这段代码的改变,这将是非常棒的。C中指针和变量之间的区别?

+4

指针和变量之间的区别是,可能应该是'INC2(一)''上的main'最后一行? – zwol

+4

此代码不能编译。 –

+1

nope,我已经完全按照它在论文中的描述写下了它。 – deanhet

回答

4

我会解释这几乎相同的代码不包含在您的文章中的错误:

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

接下来,的地址传递给inc2()。这意味着x中的值发生了什么。同样,后增为用,还等什么inc2()回报率是3,但通话结束后,a是4

然而,编译器可以自由地计算表达式,如ainc2(&a),在序列点之间的任何顺序。这意味着,对inc2(&a) + a右侧的a可以是3或4(取决于a是否之前或int2(&a)后评价,所以程序可以输出或者或。

+3

它与指针没有任何关系,但是这个程序可能合法(即两个选项都没有指出编译器中的错误)打印“6 7”或“6 8”。 (你知道为什么吗?) – zwol

+0

@Zack如果在'inc2'之前评估了'a'(这是允许的吗?),我可以看到'6 6',但我不确定'6 8'会发生什么。说明? –

+1

它可以打印67或66. +表达式的评估顺序未定义。 (只有短路东西才会被评估)@Goldilocks:但'a'已经被评估过了。 – wildplasser

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”到指针(地址)的值,但将返回的“一”旧值(3)仍由于它使用后增量运算符,但它会反过来增加'a',任何后续访问'a'都会得到新的值。下一个'a'的值为'4',因为评估是从左到右完成的,因此它将打印7(3 + 4)。

我希望澄清了C.

相关问题