否则在#define宏指令中...错误:'if'之前的预期表达式

时间:2013-12-06 08:35:33

标签: c macros

我不能在if/else, if/else if/else指令中使用#define吗?下面的代码给出了错误:

#include <stdio.h>

#define makro(a) if(a%2 == 0) 1 else 0;

int main(void) {
    // your code goes here
    int a = makro(5);
    printf("%d\n", a);
    return 0;
}

prog.c: In function ‘main’:
prog.c:3:18: error: expected expression before ‘if’
 #define makro(a) if(a%2 == 0) 1 else 0;
                  ^
prog.c:7:10: note: in expansion of macro ‘makro’
  int a = makro(5);
          ^

5 个答案:

答案 0 :(得分:5)

是。那个宏像这样扩展

int a =  if(a%2 == 0) 1 else 0;

显然这不合法。你可以尝试这个(使用三元组)。另请注意,这是按位的,相当于之前的模2。

#define makro(a) ((((a) & 1) == 0) ? 1 : 0)

当然你可以shorten多一点

#define makro(a) (!((a) & 1))

答案 1 :(得分:3)

如果您取消选中宏,则可以看到问题:

int a = if(5 == 0) 1 else 0;

这显然在语法上是不正确的(if...语句而不是表达式)。

您可以将if替换为三元(这是表达式):

int a = 5 == 0 ? 1 : 0;

并且,改造宏给出了正确的定义:

#define makro(a) ((a%2) == 0) ? 1 : 0;

我还引入了括号,以防a是一个函数,类似c++等表达式。

表达式语句

作为最后的评论,如果您使用的是GNU C,那么您可以使用表达式语句,它是非标准的C扩展名。然后,您再次收到if...声明。参见

http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

了解更多详情。

答案 2 :(得分:1)

您应该像这样定义宏:

#define makro(a) do { (a%2 == 0) ? 1 : 0; } while (0)

#define makro(a) ((a%2 == 0) ? 1 : 0) 

将semicolomn放在宏的末尾几乎总是一个坏主意,因为例如你在编写时遇到了麻烦:

printf( "Val %d", makro(a) );

如果你把semicolomn

这个宏可以更好地定义为:

#define makro(a) ((~a)&0x01) 

答案 3 :(得分:0)

在这种情况下,您应该使用ternary operator

#define makro(a) ((a) % 2 == 0) ? 1 : 0;

答案 4 :(得分:0)

答案已经存在,所以最好看到这里有两点需要注意:

  1. 代码中的宏实际上是其定义的内联扩展,就像它一样。另外,出于这个原因,不要在宏定义之后加分号。也可以将整个宏定义括在parantheses中以保证正确性。

    e.g。 #define add(a)a + a

    当使用像add(2)* add(3)将是2 + 2 * 3 + 3 = 11

    而不是预期的4 * 6 = 24。

    2.如果不形成单一陈述,则它们是连在一起的两个陈述。

    即。如果(2) - 某事 - ;别的 - 某事---;是对的。

    它不像do while循环那样do和while是单个语句。

    #include

    int main()

    {if(0); // ---------&GT;如果和其他是单独的staements

    else printf(“Hello \ n”);

    返回0;   是一个正确的程序。