2013-01-01 47 views
-3

我刚开始学习C++。请原谅这样的问题。 我的任务是编写一个宏来计算周长并对其进行测试。C++:宏似乎有点奇怪

#define _USE_MATH_DEFINES 
#include <cmath> 

#define LENGTH(radius) (2 * M_PI * radius) 

float l1 = LENGTH(1 + 2); // The result should be 18.8495... I have 8.28. Incorrect result. 
float l2 = 1/LENGTH(2); // The result should be 0.07957... Working correctly. 

我增加了额外的对parenthethis的:

float l1 = LENGTH((1 + 2)); // Correct result. 

怎么能写出这样一个宏,我得到无需添加额外的括号正确的结果?

+0

你可以做的最好的事情是编写一个'constexpr'(或不)函数。 – Griwes

+4

这里有什么奇怪的是使用宏。内联函数会更合适。 –

回答

12

使用:

#define LENGTH(radius) (2 * M_PI * (radius)) 

当你写

float l1 = LENGTH(1 + 2); 

与您定义的预处理器将其转换为

float l1 = 2 * M_PI * 1 + 2 
3

永远,永远,包宏参数在() - 无论多么它可能看起来微不足道,你迟早会需要它。

当然,编写同样功能的函数有以下好处: 1.您可以在调试器中进入,因此您可以真正弄清楚发生了什么。 2.宏观参数表达式没有奇怪。

要说明一点二,说我们使用您的宏有这样的代码:

// Print 10 lengths, 3, 5, 7, ... 
int x = 3; 
for(i = 0; i < 10; i++) 
{ 
     printf("Length of radius %d is %5.2f\n", x, LENGTH(x += 2)); 
} 

现在,有人拿了一个优化级别,并实现了2 *什么是快做的东西+什么的,所以重写宏要快:

#define LENGTH(radius) (((radius) + (radius)) * M_PI) 

现在,既然我们已经在x+=2LENGTH宏,奇怪的事情发生(因为同一个变量在同一语句[是,两者之间的平均更新两次成为未定义行为序列点]。如果有一个length函数,它会像你期望的那样完美工作。

1

不使用宏本 - 一个inline function在各方面都

更好但是发生的事情是很简单的undertand,并了解它是有用知道为什么宏最好避免。

#define LENGTH(radius) (2 * M_PI * radius) 

float l1 = LENGTH(1 + 2); 

宏是只是■简单文本替换,所以上面的代码被取代以:

float l1 = (2 * M_PI * 1 + 2); 

这显然有错误的操作优先级。