2010-04-25 92 views
1
#include<stdio.h> 

#define a(x) (x * x) 

int main() 
{ 
    int i = 3, j; 

    j = a(i + 1); 
    printf("%d", j); 

    return 0; 
} 

我想知道为什么程序没有给出输出16。 (我得到的输出7。)C程序输出


我明白了点非常多,但如果程序是这样的:

#include<stdio.h> 

#define a(x) (x * x) 

int main() 
{ 
    int i = 3, j, k; 

    j = a(i++); 
    k = a(++i); 
    printf("%d\n%d", j, k); 

    return 0; 
} 

那么为什么上面的程序给出以下的输出:

9 
49 
+1

@Paul在这种特殊情况下,如果它是作业的上下文,有什么关系?也许是这样,也许OP已经很好地将问题简化成了一个最小化的程序,它展示了令他们困惑的行为。我不是说这是一个好问题,我只是说(这一次),这不是一个坏问题,因为它可能是也可能不是家庭作业。除非作业是“为什么这个程序打印7?”,在这种情况下,作业是一个不好的问题。 – 2010-04-25 08:21:06

+1

@帕斯卡尔:主要原因在于它是作业,所以最好提供有用的提示或一般指导而不是完整的解决方案,以便帮助学生学习一些东西。如果它不是家庭作业,那么显然一个完整的解决方案是适当的。 – 2010-04-25 09:02:39

+0

@保罗好点。 – 2010-04-25 09:04:40

回答

7

因为你犯了一个糟糕的宏:

a(i + 1) 

扩展到

i + 1 * i + 1 

这相当于

i + i + 1 

2 * i + 1 

使用括号:

#define a(x) ((x) * (x)) 

然后你会得到它扩大到

(i + 1) * (i + 1) 

这你想要做什么。

+0

感谢好友.... – sandy101 2010-04-25 08:19:09

+0

你能告诉我什么是新的宏的问题.... – sandy101 2010-04-25 08:32:55

+2

@ sandy101:编辑代码的问题是,它改变'我'两次,没有介入序列点。这是调用未定义的行为。 (或者在这种情况下是_unnspecified_无论如何,结果可能会因不同编译器,月相和不同而有所不同) – sbi 2010-04-25 08:36:29

2

阅读C运算符的优先顺序,并考虑在这种情况下宏a扩展到的内容。

2

预处理线后

j=a(i+1); 

将是:

j=(i+1*i+1); 

其中当评价i=3会给j=7

j=(3+1*3+1); 

为了让你需要定义宏作为期望的结果:

#define a(x) ((x)*(x)) 

导致:

j=((i+1)*(i+1)); 

,并给出结果16i=3

+0

你能告诉我新的宏的问题 – sandy101 2010-04-25 08:33:53

1

因为a(i+1)被预处理成(i+1*i+1)

和3 + 3 + 1 = 7

您可能需要使用括号周围x

编辑:哇,这是多余的还是什么。 :/

0

因为你的宏是错的。显然它可以工作,但错误更微妙(不完全,但仍然),因为扩展的代码有一些问题,因为不遵循预期的操作顺序。

j = a(i+1)将展开为j = i + 1 * i + 17

如果你想解决您的问题重新定义宏为:

#define a(x) ((x)*(x)) 

这是很好的,你现在已经遇到了这个问题,而不是以后。这些类型的错误,有时很难调试,但现在你会知道如何编写“专业”宏:)。

0

因为(i + 1)被预处理成(i + 1 * i + 1)。

和3 + 3 + 1 = 7

您可能需要使用括号x周围。

编辑:哇,这是多余的还是什么。 :/

链接|标记