【问题标题】:If else in #define macro directive ... error: expected expression before ‘if’ [closed]#define 宏指令中的 if else ... 错误:'if' 之前的预期表达式 [关闭]
【发布时间】:2013-12-06 08:35:32
【问题描述】:

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

#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);
          ^

【问题讨论】:

  • 这与宏无关。 if 不是 C 中的表达式。阅读初学者 C 书籍/教程。

标签: c macros


【解决方案1】:

是的。那个宏是这样展开的

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 但是我会删除分号(或者如果在表达式中使用它会给出另一个错误)并且我会在参数周围添加括号(如果参数是表达式本身)和所有宏(相同原因,它可能在复杂的上下文中使用)。
  • == 将在此处以完全正确的方式计算为 1 或 0,因此整个 ?: 在技术上是多余的,尽管我想它有助于清晰。
【解决方案2】:

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

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

了解更多详情。

【讨论】:

  • 我猜应该删除那个分号,正如我上面解释的那样。顺便说一句 +1 最后的话
【解决方案3】:

你应该像这样定义宏:

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

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

将分号放在宏的末尾几乎总是一个坏主意,因为例如你会遇到麻烦:

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

如果你放分号

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

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      答案已经有了,所以最好看看这里有 2 点需要注意:

      1. 代码中的宏实际上是其定义的内联扩展。此外,出于这个原因,不要在宏定义后放置分号。此外,为了正确起见,请将整个宏定义括在括号内。

        例如#define add(a) a+a

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

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

        2.if和else不构成一个语句,它们是连接在一起的2个语句。

        即。如果(2)——某事——;否则——某事——;是正确的。

        它不像 do while 循环,其中 do 和 while 是一个语句。

        #包括

        int main()

        { 如果(0) ; //---------> if 和 else 是独立的语句

        else printf("你好\n");

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-04
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        • 1970-01-01
        相关资源
        最近更新 更多