MY_PRINT
是整个代码中的一个宏,它只是printf。
我想暂时修改它以在每次printf之后附加\ n。
然而,当我这样做时:
#define SENS_PRINT(x) printf(x); printf("\n")
MY_PRINT( "\n #%d: %c ", ++command_line_number, sensor_operation_code );
...输出为垃圾:#3405240: <alpha symbol>
这打印好,但最后没有\ n:
#define SENS_PRINT printf
答案 0 :(得分:4)
您希望您的宏能够采用各种参数,就像真正的printf一样。您可以使用可变参数宏来执行此操作。
当宏是条件代码块中唯一的表达式时,还存在两个单独的表达式不被解释为宏所暗示的危险。想想如果你说if (flag) SENS_PRINT(...);
宏会做什么。防止这种情况的一种方法是将宏包装在do { ... } while(0)
块中。
向printf
添加换行符的可变参数宏可能如下所示:
#define PRINTFLN(...) do { printf(__VA_ARGS__); puts(""); } while (0)
您可以像printf
:
PRINTFLN("Hello %s!", "cruel world");
if (flag) PRINTFLN("%d + %d == %d", x, y, sum);
答案 1 :(得分:2)
C语言允许您连接由空格分隔的字符串文字。如果您对MY_PRINT
的所有调用都使用字符串文字作为其格式化参数,则可以定义一个可变宏,它将"\n"
直接附加到您的格式字符串,然后应用其余的参数。< / p>
像这样定义你的宏
#define MY_PRINT(format, ...) printf(format "\n", __VA_ARGS__)
您将能够直接在格式化参数中添加换行符。
使用此方法只会执行一个函数调用,但使用除字符串文字以外的任何其他格式调用将导致编译错误。
答案 2 :(得分:1)
函数行宏的问题在于,预处理将所有逗号分隔的参数视为宏的参数,而不是单个参数。所以你的编译器应该抱怨你传递给宏的许多参数。
一个简单的解决方案是将宏参数括在括号中:
MY_PRINT( ( "\n #%d: %c ", ++command_line_number, sensor_operation_code ) );
// ^ ^
// | |
// Note extra parentheses here... and here
另一种解决方案是使用variadic macros。
在某种程度上相关的说明中,您所显示的宏不能在构造中使用,例如。
if (some_condition)
MY_PRINT(...);
将替换为
if (some_condition)
printf(...);
printf(...);
如果宏中有多个语句,则需要将其括在一个块中,例如
#define MY_PRINTF(...) \
do { \
statement1; \
statement2; \
. \
. \
. \
statementN; \
} while (0)