2011-03-07 64 views
3

我想解决两个预处理器相关的问题,但在这两个程序中我得到的结果,我无法弄清楚如何。下面是我的程序:为什么我的C程序输出这个?

#include<stdio.h> 
#define SQUARE(x) x*x 
int main() 
{ 
float s=10,u=30 ,t=2,a; 
a=2*(s-u*t)/SQUARE(t); 
printf("Result:%f\n",a); 
return 0; 
} 

据对我来说,这个程序的输出应该是-25.000但我正在逐渐-100.000

而在第二个方案:

#define FUN(i,j) i##j 
int main() 
{ 
int val1 = 10; 
int val12 = 20; 
clrscr(); 
printf("%d\n",FUN(val1,2)); 
getch(); 
} 

输出应该是102但我正在逐渐20; 这是为什么呢?

+0

我怀疑的#include> stdio.h>中 甚至会编... – PhiLho 2011-03-07 12:01:39

+0

对不起@PhiLho它的#include 2011-03-07 12:18:56

+0

你的第二个例子就不会编译。请复制/粘贴您使用的确切源代码。 – 2011-03-07 12:33:13

回答

4

第一个:

a=2*(s-u*t)/SQUARE(t); 

更换后定义,我们得到:

a=2*(s-u*t)/t*t; 

现在,因为我们没有在SQUARE的定义()我们得到:

a=2*(10-30*2)/2*2; --> a=2*(-50)/2*2; --> a=-100/2*2; --> a=-50*2; --> a=-100 

如果你想得到-25你应该定义SQUARE(x)(x*x)

编辑:添加关于第二个例子的解释。

printf("%d\n"FUN(val1,2)); 

再次,我们首先应该更换的定义(提醒:##“会连接”的字符串的定义 - 我无法找到完美的话,以解释所以只是来看看的例...):

printf("%d\n",val12); [note: the comma (,) is missing - so it won't compile.] 

val1220那就是你会得到什么。

的那些两个例子的一点是要记住,我们要始终处理定义第一(因为“现实生活”的编译器(或预处理器)做它的运行时间之前)

希望它可以帮助..

+0

感谢@SivGo为您解释,并且还有一个事实,即/ *操作符具有从左到右的关联性.... – 2011-03-07 12:25:47

+0

并且无法获得第二个问题 – 2011-03-07 12:26:56

+0

printf(“%d \ n”,FUN(val1 ,2));这里val1的值不会替换为10?这是我感到困惑的地方......我认为它应该被10代替...... – 2011-03-07 13:00:45

11
#define SQUARE(x) x*x 

应该

#define SQUARE(x) ((x)*(x)) 

事实上,如果没有括号,如

2*(s-u*t)/t*t 

这被解释为

(2*(s-u*t)/t)*t 

关于你的第二个问题2*(s-u*t)/SQUARE(t)扩大, 0根据##运算符的语义,将被扩展为val12。它仍然是不明确你的目的是什么:在printf线将被理解为

printf("%d\n", val12); 

,它将打印20

+0

同样举例二,'(i ## j)' – alternative 2011-03-07 11:57:14

+0

谢谢@Alexandre。这个a =(2 *(s-u * t)/ t)* t;表达式是根据#define SQUARE(x)x * x,这就是你想说的 – 2011-03-07 12:22:31

+0

为什么要这样定义FUN:#define FUN(i,j)(i ## j)会解决这个问题吗? – SivGo 2011-03-07 13:16:11

3

对于第一种情况,

a=2*(s-u*t)/SQUARE(t); 

会在编译时转换为

a=2*(s-u*t)/t*t; 

。这是预处理器常犯的错误。

相关问题