是否可以在#define中使用if语句?

Fre*_*337 14 c macros if-statement c-preprocessor

我正在尝试使用以下公式制作一个宏:(a^2/(a+b))*b,我想确保不会有零除以.

#define SUM_A( x, y ) if( x == 0 || y == 0) { 0 } else { ( ( ( x * x ) / ( ( x ) + ( y ) ) ) * ( y ) )}
Run Code Online (Sandbox Code Playgroud)

然后我调用main里面的宏:

float a = 40, b = 10, result; 
result = SUM_A(a, b); 
printf("%f", result);
Run Code Online (Sandbox Code Playgroud)

我尝试在if函数周围使用括号,但我在if语句之前一直遇到语法错误.我也尝试过使用return,但我在某处读到你不应该在define中使用它.

tom*_*ahh 22

你不能使用if语句,因为它#define是由预处理器解释的,输出就是

 result=if( x == 0 || y == 0) { 0 } else { ( ( ( x * x ) / ( ( x ) + ( y ) ) ) * ( y ) )}
Run Code Online (Sandbox Code Playgroud)

这是错误的语法.

但另一种方法是使用三元运算符.将您的定义更改为

#define SUM_A( x, y )  ((x) == 0 || (y) == 0 ? 0 : ( ( ( (x) * (x) ) / ( ( x ) + ( y ) ) ) * ( y ) ))
Run Code Online (Sandbox Code Playgroud)

请记住始终将您的定义放在括号之间,以避免在替换时出现语法错误.


Fre*_*Foo 6

if介绍一个陈述,而不是一个表达.使用"三元"(条件)运算符:

#define SUM_A(x, y) (((x) == 0 || (y) == 0)? 0: ((((x) * (x)) / ((x) + (y))) * (y)))
Run Code Online (Sandbox Code Playgroud)

或者,使这个inline功能:

inline float sum_a(float x, float y)
{
    if (x == 0 || y == 0)
        return 0;
    else
        return ((x * x) / (x + y)) * y;
}
Run Code Online (Sandbox Code Playgroud)

这避免了多重评估x和/或y更具可读性的问题,但它确实修复了x和的类型y.您也可以删除inline并让编译器决定是否值得内联此函数(inline不保证它将执行内联).


Sae*_*aig 6

从技术上讲,可以以(但不能以您期望的方式)使用if语句#define。由于#defines只是文本替换,因此在扩展它时必须非常小心。我发现这可行...

#define SUM_A(x, y)                                        \
({                                                         \
    double answer;                                         \
    if ((x) == 0 || (y) == 0)                              \
        answer = 0;                                        \
    else                                                   \
        answer = ((double)((x)*(x)) / ((x)+(y))) * (y);    \
    (answer);                                              \
})
// Typecasting to double necessary, since int/int == int in C
Run Code Online (Sandbox Code Playgroud)

这应该可以为您提供所需的结果,并且没有理由也不能将其扩展为包含多个else ifs(尽管正如其他答案所指出的那样,使用三元运算符可能更容易)。