C++中的宏

C++中的宏

宏的作用

1. 定义常量

#define NUM 100

上述代码是一种非常见的宏定义, 定义一些常见的常量, 如数学公式中常用的PI等常数。因为宏只是做简单的替换,并不会做类型检查,因此使用的时候可能带来一些负面影响。

// TODO 宏定义的常量与const 定义的常量的区别

2. 条件编译
条件编译的作用主要体现在两个方面:头文件的包含和代码的选择编译。

在构建工程的时候, 一般通过#include来包含其他头文件。#include 的处理过程就是将被包含的文件“复制粘贴”到当前文件中, 如果直接或者间接地重复包含了同一个头文件,可能就会导致重复定义等问题。此时可以使用宏定义来避免这一类事情的发生。(也可以使用 #pragma once 来实现该功能, 但此命令跨编译器支持不够好)

#ifndef _HEADER_H_
// some codes
#endif // _HEADER_H_

第二种就是有选择性的编译代码。比如在开发的过程中,常常需要打印一些信息来检查代码运行的正确性。但在最终交付的时候又不需要这些冗余的代码。此时就可以通过宏定义来作为编译的开关, 避免在最终的编译过程中产生不必要的代码。

#ifdef  _DEBUG
// run debug codes
#else 
// run release codes
#endif  // _DEBUG

3. 定义函数
一些简单的函数也可以使用宏来实现。因为宏是做简单的替换,并不涉及编译,因此宏展开的函数并不会在代码中产生函数的调用开销, 非常简单高效。值得注意的是,尽量给”参数“加上括号, 防止替换的时候产生歧义,造成错误。

同时利用系统定义的可变参数宏, 也能很简洁地实现一些函数,大量简化代码。

#define MIN(a, b) ((a) < (b) ? (a):(b))
#define LOG( format, ... ) printf( format, __VA_ARGS__ )

4.字符串处理
宏有两个特殊的符号 ###。 前者是将输入的参数字符串化, 即在参数的两端加上双引号; 而后者是做字符串拼接的。

#define STR(a)  #a
#define STR_CONTACT(a, b)   a##b

宏的展开

宏定义中可以再次添加已经定义过的宏,因此可以实现宏的嵌套。嵌套后的宏定义如何展开,有着一定的规则:

  1. 实参带入宏文本后,实参之前或者之后遇到#或者##, 均不对其展开。
  2. 宏展开后遇到“自己”, 则不展开,防止递归展开。
  3. 带参数的宏,在使用的时候必须加上括号和参数,否则会当做普通的字符,不做展开。
  4. 最外层的括号内的逗号视为参数分隔符,最内层暂时不视为参数分隔符。
  5. 宏展开从内层开始进行。
  6. 每次展开后都会记住展开的宏,后续不再展开相同的宏。

宏展开的大致顺序可以描述为:
1、实参替换, 将宏文本中的形参使用实参进行替换
2、如果实参也是宏,则继续展开实参
3、继续展开宏替换后宏文本,如果遇到#或者##则不展开。

#define PARAM(x) x
#define PARAM_CAT(x) INT_##x

PARAM_CAT(PARAM(100));
//这条宏语句的展开大致过程为:
//先展开PARAM(100), 得到 PARAM_CAT(100)
//再接着展开 PARAM_CAT(100), 得到 INT_100

利用宏展开的机制, 可以写出简单的宏, 来查看宏展开的结果:

#define STR(x)  #x
#define MACRO_UNWARP(x) STR(X)
#define MACRO_T() AAAAA 

// 这样很方便查看展开后的宏是什么样的, 有助于调试宏的编写。
std::cout << MACRO_UNWARP(MACRO_T()) << std::endl; 

宏展开的结果在linux下可以使用编译器的-E命令来查看宏展开后结果。

gcc -E a.cpp | more

参考

[0] C 和 C++ 宏 详解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值