我试过这样定义:
#define Math.Pow(a,b) (int result=1; for (int i=0; i<b; i++) result*=a; return result;)
当我在代码中使用Math.Pow(a,b)
时,我得到一个错误:
期望一个表达式。
我试图把这个定义放在另一个函数中,比如
int Power(int a, int b)
{int result=1; for (int i=0; i<b; i++) result*=a; return result;}
和
#define Math.Pow(a,b) (Power(a,b))
但是我得到了相同的错误
不能在宏名中使用.
字符。即使可以,宏中的return
语句也不会从宏本身返回值。请记住,宏只是在编译器被调用之前的文本替换,因此return
将应用于调用代码,这不是您在这种情况下真正想要的。
要做你正在尝试的事情,使用模板化函数代替:
struct Math
{
template<typename T>
static T Power(T a, T b)
{
T result = 1;
for (int i = 0; i < b; ++i)
result *= a;
return result;
}
};
或:
namespace Math
{
template<typename T>
T Power(T a, T b)
{
T result = 1;
for (int i = 0; i < b; ++i)
result *= a;
return result;
}
}
无论哪种方式,你都可以这样调用它:
Math::Power(value1, value2);
除了名称中的.
问题之外,您的宏引入了多个语句,这些语句用括号分组,例如(statement;声明;语句。)这不是合法的C/c++语法。但是,您可以使用逗号操作符对多个单独的表达式求值(但不能执行多个任意语句)。然而,有很多更好的方法来做你想做的事情。
讨论
使用宏时,预处理器在编译器之前运行,并将代码中的宏替换为指定的别名文本。
您的第一个问题是宏的名称包含点.
。这是不允许的,因为宏的名称是一个标识符。标识符名称不允许使用点字符,因为.
用于operator.
(即点操作符)。所以编译器的抱怨是正确的。
假设我们通过为宏使用一个合法的名称来克服这个问题,例如Math_Pow
。
现在让我们假设你有以下一段代码:
#define Math_Pow(a,b) (int result=1; for (int i=0; i<b; i++) result*=a; return result;)
int main () {
Math_Pow(1, 3);
}
现在,当你的宏将被预处理器替换为上面代码中的别名文本时,编译器的代码提要将是:
int main () {
(int result=1; for (int i=0; i<b; i++) result*=a; return result;)
}
以上不是合法的c++,所以编译器再次报错。
现在假设我们使用大括号代替圆括号(例如,。#define Math_Pow(a,b) {int result=1; for (int i=0; i<b; i++) result*=a; return result;}
)
现在代码变成:
int main () {
{int result=1; for (int i=0; i<b; i++) result*=a; return result;}
}
上面的代码在语法上是正确的,但是它有一个逻辑缺陷。如果return
是main
的result
。这意味着如果你在一个函数中声明这个修正过的宏,这个函数将会return
,这显然是你不希望这个宏做的事情。
- 标准数学库已经有
pow
的版本。 - 定义宏为内联函数:
inline int Power(int a, int b) {
int result = 1;
for (int i = 0; i < b; ++i) result *= a;
return result;
}