主题有以下代码,这是指示错误位置所必需的。
#include<iostream>
#define PT 3.5;
#define S(x) PT*x*x
void main() {
int a = 1, b = 2;
std::cout << S(a + b);
}
我认为"quot;导致此问题,并删除了";"编译后的测试可以得到正确的结果。但是老师认为变量不能用于宏观定义。我不确定谁是对的。
我看到了很多答案,但我想知道的不是这样写是否合理,而是到底是什么导致了程序错误。
添加";"在"#define"之后不是特别好,但编译可以通过#定义";也可以允许变量出现。所以最后的错误原因是"*a+b";?
有几个问题。是的,PT
将扩展到3.5;
,并导致语法错误。将其更改为:
#define PT 3.5
另一个问题是S(a + b)
将扩展到PT*a + b*a + b
,这显然不是您想要的。按照惯例,执行算术的宏应该将任何可扩展部分封装在括号中,整个宏也应该包含在括号中:
#define S(x) ((PT)*(x)*(x))
这样可以确保您不必担心扩展表达式会因运算符优先级规则而造成严重破坏。
关于对你老师的评论。。。
老师认为变量不能用于宏定义
他们可能在谈论x
只是扩展的占位符这一事实。如果通过a + b
并使用x
两次,则a + b
将被评估两次。想象一下,如果你打电话给S(++a)
。。。你会得到PT*(++a)*(++a)
通常只编写一个函数更合适,这样可以避免出现上述问题。
double S(int x) {
return PT * x * x;
}
甚至:
template<class T>
double S(T x) {
return PT * x * x;
}
宏只是文本替换,所以只要替换的结果是有效的代码,你几乎可以做任何你想做的事情。因此,";可以';'在CCD_ 11"之后添加;是的,但结果可能不起作用。
#define calc(x) ((x) * (x));
void f() {
int g = 3;
int h = calc(g);
}
宏扩展的结果是
int h = ((g) * (g));;
这是有效的代码;第二个分号标记一个空表达式的末尾,就像它是一样
int h = ((g) * (g));
;
当然,这是一种糟糕的风格,它可能会在其他情况下引发问题,所以";右";使用该宏的方法是
int h = calc(g)
这样,宏展开后的文本将只有一个分号。但这看起来很奇怪,而且宏真的中不应该有分号
至于使用变量,同样,这取决于文本替换的结果
#define calc (x) * (x)
void f() {
int x = 3;
int y = calc;
}
没关系;该代码相当于
void f() {
int x = 3;
int y = (x) * (x);
}
另一方面,这是不好的:
void f() {
int b = 3;
int y = calc;
}
它不起作用,因为那里没有x
。因此,这个宏的用处有限;在极少数情况下,这可能是合适的,但总的来说,这是个坏主意。
不能在PT后面加分号,因为宏S(X) PT*x*x
将被处理为3.5;*x*x
您的S(x)
宏正在中断,因为分号将其分为2条语句。第一个是3.5;
,第二个是*x*x
因此您会出现错误。
要使其工作,您只需删除PT 定义中的;