#define DORECOVERY()/
LED_RUN=1;/
VAL1=OFF;/
VAL2=OFF;/
PUMP=OFF;/
VAL3=ON;/
COMPRE=ON;
#define STR_OUTPUT_FORMAT_V0 "%s%s%s/n"
printf(STR_OUTPUT_FORMAT_V0, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
由于真实代码中这个串很长,所以打算美化一下格式,定义成下面的样子:
#define STR_OUTPUT_FORMAT_V1 "%s/
%s/
%s/n"
printf(STR_OUTPUT_FORMAT_V1, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
这样的定义显然不对,也在我意料之中,续行符将空格也续到格式串中了,导致输出的结果中带有大量空格。
改进一下,利用C语言的字符串自动连接语法。
#define STR_OUTPUT_FORMAT_V2 "%s"/
"%s"/
"%s/n"
printf(STR_OUTPUT_FORMAT_V2, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
现在的问题是如何在这样一个多行的宏定义里加入注释,字段含义特殊,加上注释有利于以后维护以及别人阅读你的代码,否则一堆%s%s,让人看了就头痛。先这么加试试:
#define STR_OUTPUT_FORMAT_E1 "%s"/ /* comment1 */
"%s"/ /* comment2 */
"%s/n" /* comment3 */
printf(STR_OUTPUT_FORMAT_E1, "hello ", "macro, ", "yeah!");
我们得到的结果:编译错误。
通过gcc -E 选项我们看到,宏替换后的代码:
"%s"/
"%s/n"
int main() {
printf("%s"/, "hello ", "macro, ", "yeah!");
}
由于没有续行符在注释前面,所以宏定义的后两行实际上并没有被包含在宏定义中,就像没有暂住证的人一样,被GCC这个"警察"逮个正着。
继续改进:
#define STR_OUTPUT_FORMAT_V3 "%s" /* comment1 */ /
"%s" /* comment2 */ /
"%s/n" /* comment3 */
printf(STR_OUTPUT_FORMAT_V3, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
显然预编译器忽略宏定义中的注释以及空格,STR_OUTPUT_FORMAT_V3就完全符合我的要求了。
当然,很多人不建议使用宏,特别是C++的Fans,宏也的确有很多弊端,这里也有替代方法:
const char *str_output_format = "%s" /* comment1 */
"%s" /* comment2 */
"%s/n"; /* comment3 */
printf(str_output_format, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
下面是用Dev-C++4.9.9.2写的程序:
/****************************************************************************
//文件名称:macro.c
//功 能:test many lines in macro
//作 者:LanMaoAiFei
//建立日期:2010.09.25
//版 本:V1.0
//备 注:Compiler-Dev-C++4.9.9.2
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define STR_OUTPUT_FORMAT_V0 "%s%s%s/n"
#define STR_OUTPUT_FORMAT_V1 "%s/
%s/
%s/n"
#define STR_OUTPUT_FORMAT_V2 "%s"/
"%s"/
"%s/n"
#define STR_OUTPUT_FORMAT_V3 "%s" /* comment1 */ /
"%s" /* comment2 */ /
"%s/n" /* comment3 */
const char *str_output_format = "%s" /* comment1 */
"%s" /* comment2 */
"%s/n"; /* comment3 */
/*************************************************************************
//函数名称:int main(void)
//功 能:主函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
*************************************************************************/
int main(void)
{
printf(STR_OUTPUT_FORMAT_V0, "hello v0 ", "macro, ", "yeah! //this will display correct ^_^ ");
printf(STR_OUTPUT_FORMAT_V1, "hello v1 ", "macro, ", "yeah! //this will display wrong with many blank -,- ");
printf(STR_OUTPUT_FORMAT_V2, "hello v2 ", "macro, ", "yeah! //this will display correct ^_^ ");
printf(STR_OUTPUT_FORMAT_V3, "hello v3 ", "macro, ", "yeah! //this will display correct ^_^ ");
printf(str_output_format, "hello const ", "macro, ", "yeah! //this will display correct ^_^ ");
system("pause");
//while(1);
return 0;