如何创建多行预处理器宏?我知道如何创建一行:
#define sqr(X) (X*X)
但我需要像这样的东西:
#define someMacro(X)
class X : public otherClass
{
int foo;
void doFoo();
};
如何让这个起作用?
这只是一个例子,真正的宏可能非常长。
如何创建多行预处理器宏?我知道如何创建一行:
#define sqr(X) (X*X)
但我需要像这样的东西:
#define someMacro(X)
class X : public otherClass
{
int foo;
void doFoo();
};
如何让这个起作用?
这只是一个例子,真正的宏可能非常长。
你使用 \
作为换行符的转义字符。
#define swap(a, b) { \
(a) ^= (b); \
(b) ^= (a); \
(a) ^= (b); \
}
编辑: 如@abelenky在评论中指出,\
字符必须是行尾最后一个字符。如果不是(即使后面只有空格),在其后的每一行都会产生令人困惑的错误消息。
\
,然后添加注释,比如 // 宏定义后需要空白行
。确保所有宏定义的行都以 \
结尾有时比确保除最后一行外的所有行都这样做要容易些。 - supercat通过在每行末尾添加反斜杠 (\
),您可以使宏跨越多行:
#define F(x) (x) \
* \
(x)
#define sqr(x) ((x)
(x))
请注意- Ed S.在此帖子后编辑了他的答案。
sqr(++i)
怎么样?(假设我们有一个int i
):) - Géza Töröki
在被宏替换时被递增(在这种情况下它被替换了两次),然后被乘。因此,sqr(++5) == ((7) * (7))
。 - jiveturkey@GézaTörök
,将sqr(++i)
展开为((++i)*(++i))
会引起未定义行为,因为该语句中i
的值被修改了多次(操作之间没有顺序点)。 - moooeeeep虽然这不是原始问题的一部分,但其他答案都没有提到在多行宏中嵌入的注释需要特别注意。
例子:
// WRONG:
#define someMacro(X) \
// This comment is a problem. \
class X : public otherClass \
{ \
int foo; \
void doFoo(); \
};
// WRONG:
#define someMacro(X) \
/* This comment is also \
* a problem. */ \
class X : public otherClass \
{ \
int foo; \
void doFoo(); \
};
// OK:
#define someMacro(X) \
/* This comment is fine. */ \
class X : public otherClass \
{ \
int foo; /* This is OK too! */ \
void doFoo(); \
};
您需要通过在末尾使用\
进行转义,来转义该行末尾的换行符:
#define sqr(X) \
((X)*(X))
现在已经是2021年了,我们应该真正开始向inline
转变。不正确、不必要和过度使用宏会使代码膨胀,并且它们很难调试(读起来真的很难调试)。
inline void foo(x)
{
// do whatever with x
}
如果宏确实是当务之急,那么将它们包围在 do { } while(0);
中的原因在这篇文章中有解释:为什么在宏中使用看似无意义的 do-while 和 if-else 语句?
do { /* code */ } while (0)
习惯用法。我认为这是需要更广泛传播的知识,因为我仍然看到有人使用简单的 { /* code */ }
编写多行宏,然后在分号上马虎。 - phetdamdo { /* code */ } while (0)
的多行宏语法。我认为这是需要更广泛传播的知识,因为我仍然看到有人使用简单的 { /* code */ }
编写多行宏,然后在分号上变得懒散。 - phetdam"\"
结尾。让我们通过示例来看看。下面是一个简单的宏,它接受用户输入的数字,并打印出输入的数字是偶数还是奇数。#include <stdio.h>
#define MACRO(num, str) ({\
printf("%d", num);\
printf(" is");\
printf(" %s number", str);\
printf("\n");\
})
int main(void)
{
int num;
printf("Enter a number: ");
scanf("%d", &num);
if (num & 1)
MACRO(num, "Odd");
else
MACRO(num, "Even");
return 0;
}