3

我正在尝试解决两个与预处理器相关的问题,但是在这两个程序中我都得到了我无法弄清楚的结果。下面是我的程序:

#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;为什么会这样?

4

4 回答 4

11
#define SQUARE(x) x*x

应该

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

事实上,没有括号,2*(s-u*t)/SQUARE(t)扩展为

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

这被解释为

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

至于您的第二个问题,FUN(val1,2)将根据运算符val12的语义进行扩展##。目前尚不清楚您的意图是什么:该printf行将被理解为

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

这将打印20.

于 2011-03-07T11:56:05.220 回答
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.]

因为价值val12就是20你会得到的。

这两个例子的重点是记住我们应该总是首先处理定义(因为在“现实生活”中编译器(或预处理器)在运行时之前完成它)

我希望它有帮助..

于 2011-03-07T12:05:56.030 回答
3

对于第一种情况,

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

将转化为

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

在编译时。这是预处理器常犯的错误。

于 2011-03-07T11:58:02.333 回答
0

我知道我迟到了,但我有完美的答案。

在 c# 中,at define 用于调用函数参数中的文本,

例如,#define hai(s1) printf("%s=%s",#s1,s1);

       in main: i am calling as hai(tom); tom was initialized as "india" string.

这个的输出是 tom=india,调用字符串 tom 是在 # 的帮助下打印出来的。

类似地,## 用于从函数参数中获取文本并将它们连接起来并返回连接标识符的值。

上面的程序有两个参数 va1 和 2。传递给 i 和 j。然后加入 va1 和 2。并形成 va12。

va12 是可用的标识符,值为 20。这就是返回 20 的原因。

于 2019-05-05T21:22:21.993 回答