C++预处理(二) —— #define

#define 定义一个符号

#define PI 3.1415926    //定义π
#undef PI               //取消定义

3.14159265在这里不是一个数值,只是一个字符串,编译的时候不会进行检查,在编译前,预处理器会遍历代码,在它认为置换有意义的地方,用字符串PI的定义值(3.14159265)来代替,在注释或字符串中的PI不进行替换。#undef PI之后不再有PI这个标识符。

#define的缺点:

  1. 不支持类型检查
  2. 不考虑作用域
  3. 符号名不能限制在一个命名 空间中
#define PI 3.14159265
const long double PI=3.14159265;

在C中常以#define来定义符号常量,但在C++中最好使用const 来定义常量,两者比较下,前者没有类型的指定容易引起不必须的麻烦,而后者定义清楚,所以在C++中推荐使用const来定义常量

#define 定义宏

#define Print(Var) count<<(Var)<<endl

用宏名中的参数带入语句中的参数,宏后面没有;号,Print(Var)中的Print和(之间不能有空格,否则(就会被解释为置换字符串的一部分。调用

Print(ival, 15)

预处理器就会把它换成

cout << setw(15) << (ival) << endl;

调用 result = max(myval, 99); 则换成 result = myval>99?myval:99; 这个没有问题是正确的
调用result = max(myval++, 99); 则换成 result = myval++>99?myval++:99; 这样如果myval>99那么myval就会递增两次,这种情况下()是没什么用的如result=max((x),y)result = (myval++)>99?(myval++):99;再如

#define product(m,n) m*n

调用result = product(5+1,6);则替换为result = 5+1*6; 所以产生了错误的结果,此时应使用()把参数括起

#define product(m,n) (m)*(n)

result = product(5+1,6);则替换为result = (5+1)*(6); 所以产生了错误的结果,此时应使用()把参数括起
结论: 一般用内联函数来代替预处理器宏
技巧:

1. 给替换变量加引号

#define MYSTR "I love you"

cout << MYSTR ; //I love you而不是"I love you"
如果
cout << "MYSTR" ; //则会输出"MYSTR"而不是"I love you"
可以这样做
cout << #MYSTR; //则会输出 "I love you"即cout << "\"I love you\"";

2. 在宏表达式中连接几个参数

#define join(a,b) ab这样不会理解为参数a的值与参数b的值的连接,即如join(10,999)不会理解为10999而是把ab理解为字符串,即输出ab
这时可以

#define join(a,b) a##b

join(10,999)就会输出10999

3. 逻辑预处理器指令

#if defined CALCAVERAGE#ifdef CALCAVERAGE

int count=sizeof(data)/sizeof(data[0]);
for(int i=0; i<count; i++)
average += data;
average /= count;
#endif

如果已经定义符号CALCAVERAGE则把#if与#endif间的语句放在要编译的源代码内
防止重复引入某些头文件

#ifndef COMPARE_H
#define COMPARE_H //注意: 这里只是定义一个没有值的符号COMPARE_H, 下面的namespace compare不是COMPARE_H的 内容,这里的定义不像是定义一个常量或宏,仅仅定义一个符号,指出此符号已定义,则就会有下面的 内容namespace compare{...
namespace compare{
double max(const double* data, int size);
double min(const double* data, int size);
}
#endif

比较

#define VERSION \
3

因为有换行符\ 所以上句等价于#define VERSION 3
由此可以看出#define COMPARE_H与namespace compare是独立没有关系的两个行
也可以这样用

#if defined block1 && defined block2
...
#endif
#if CPU==PENTIUM4
...
#endif
#if LANGUAGE == ENGLISH
#define Greeting "Good Morning."
#elif LANGUAGE == GERMAN
#define Greeting "Guten Tag."
#elif LANGUAGE == FRENCH
#define Greeting "Bonjour."
#else
#define Greeting "Hi."
#endif
std::cout<<Greeting << std::endl;
#if VERSION == 3
...
#elif VERSION == 4
...
#else
...
#endif

#define与if条件语句灵活运用

符号说明
#define定义一个预处理宏
#undef取消宏的定义
#if编译预处理中的条件命令,相当于C语法中的if语句
#ifdef判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef与#ifdef相反,判断某个宏是否未被定义
#elif若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
#else与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
#endif#if, #ifdef, #ifndef这些条件命令的结束标志.

1. 当程序中部分代码想进行屏蔽时,就可以使用

#if 0
...
#endif

2. 当程序中部分代码有些时候想使用,有些时候不想使用的时候想进行屏蔽时,就可以使用

#ifdef TCP
...//当宏TCP被定义的时候就会执行此段代码
#elif
...//当宏TCP没有被定义的时候就会执行此段代码
#endif

通过上边的程序我们能够看出,如果想对程序进行修改的时候只需要对某个宏进行定义即可,方便快捷。

参考

C++预处理-百度百科
条件编译#ifdef的妙用详解_透彻 - MARS_Turing的博客 - CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值