预处理器和宏

简单宏定义

#define A (10)
#define func(x) x++;\            //Wrong
                x = x+10;
#define max(a,b) ( ((a)>(b)) ? (a):(b))
// notice :max(a++,a++);
#define DEBUG(x) printf(x)  //for debug
#define func(x) do\         //right
                {\
                  x++;\
                  x*=10;\
                } while(0)
//注意空格                
#define f (x) ((x)+1)
#define f(x) ((x)+1)//和上面的不同

//断言宏定义
#define assert(e) \
        ((void)((e)||_assert_error(__FILE__,__LINE__))

//定义调试宏DEBUG
#define DEBUG(fmt,..) fprintf(stderr,fmt,__VA_ARGS__)
//定以后,按照printf使用DEBUG即可
//发布程序时,修改如下
#define DEBUG(fmt,..) 

复杂宏定义

//定义接受可变参数个数的宏
#define debugprint(...) printf("DEBUG:" __VA_ARGS__);
//使用上述宏
debugprint("Hello World!\n");//对于C编译器来说,2个常量字符串会合并成1个
debugprint("i=%i,j=%i\n",i,j);

//使用#操作符
#define str(x) # x
str (testing) 会展开成 "testing"
//在宏定义的参数前面放置#,可以使用该参数生成一个常量字符串
printf("Hello World!\n"); 等效于 printf(str (Hello World!\n));
str ("hello") 展开成 "\"hello\""

//#的正确打开方式
#define printint(var) # printf(#var " = %i",var)
printfint(count);//将被展开为
printf("count"" = %i",count);
//使用##操作符
//宏定义中使用##可以把两个符号连接起来,该操作符的前面或者后面可以是宏的参数
#define printx(n) printf("%i\n",x ##n)

printx(20);//展开为
printf("%i\n",x20);

#define printx(n) printint(x ## n)
printx(10)//被展开为
printint(x10);//继续展开
printf("x10 = %i\n",x10);
  • 不能忽视宏定义中的空格
  • 添加完善的括号
  • 添加了括号,依旧不能保证没有问题,比如一个操作数如果在两处被用到,就会求值两次

条件编译

  • 预处理宏可用于编写平台无关的代码
#ifdef UNIX
#define DATADIR "/uxn1/data"
#else
#define DATADIR "\uxn1\data"
#endif
//注意绝大部分编译器允许在编译命令行输入中定义宏
gcc -D UNIX program.c
  • 避免多次包含同一个头文件
#ifndef _MYSTDIO_H
#define _MYSTDIO_H
...
#endif
#if OS==1
...
#elif OS==2
...
#elif OS==3
...
#else
...
#endif

//
gcc -D OS=2 program.c
//用defined来判断某个符号是否已经定义
#if defined(DEBUG)
...
#endif
//等价于下面
#ifdef DEUG
...
#endif
#if defined(WINDOES) || defined(WINDOWSNT)
#define BOOTDRIVE "C:/"
#else
#define BOOTDRIVE "D:/"
#endif
//用#undef来取消某个名字的宏
#undef name
//#error 后面的text将会被预处理器作为错误信息输出
#error text
//预定义的符号
__LINE__ //当前编译的行号
——FILE__ //当前正在编译的文件 
__DATE__ //当前的日期
__TIME__ //当前的时间
__STDC__ //编译器符合ANSI标准,为1
__STDC_HOSTED__ //实现了所有C标准,为1
__STDC_VERSION__ //被定义为199901L
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值