C语言进阶——4.宏定义
1. 宏定义是什么?
宏是用来表示一段代码的标识符。
宏也是标识符,也要满足标识符的规则。但通常习惯使用大写字母和下划线命名。
2. 宏定义怎么用?
宏定义通常有三种用法:
- 当作常量使用。
- 当作函数使用。
- 编译预处理。
2.1 宏定义常量
2.1.1 预定义宏
ANSI C标准定义有些定义好的宏定义,称为预定义宏。这些宏定义以双下划线__
开头结尾。
printf("%s:%d",__FILE__,__LINE__);
printf("%s:%s",__DATE__,__TIME__);
2.1.2 自定义宏
除了使用标准定义的宏,可以使用#define
指令用来定义一个宏。
#define 标识符 值
#define PI 3.1415926
说明
- 注意没有结尾的分号,因为不是C的语句。
- 名字必须是一个单词,值可以是各种东西。
- 在C语言的编译器开始之前,编译预处理程序会把程序中的名字换成值。是完全的文本替换。
- 如果一个宏的值有其他宏的名字,也会被替换。
#define PI_2 2*PI
- 如果一个宏的值超过一行,最后一行之前行末需要加\。
#define PI_2 2 \
* \
PI
#define PI_2 2*PI // 二倍的PI
2.2 带参数的宏
宏可以带参数,使用上有些像函数。这种宏称为带参数的宏。
#define 标识符(参数...) 代码
#define square(x) ((x)*(x))
#define cube(x) ((x)*(x)*(x))
#define square(x) x*x
#define cube(x) x*x*x
square(10);
cube(10);
square(10+1);
cube(10+1);
说明
#define MIN(a,b) ((a)<(b)?(a):(b))
尽量避免使用宏定义。
2.3 编译预处理
有时我们会使用没有值的宏,这种宏用于条件编译的,#ifdef
#ifndef
用于检查宏是否被定义过。控制代码的编译。
#define _DEBUG
#ifdef TEST
printf("Test\n");
#else
printf("No Test\n");
#endif
3. 宏展开
宏的本质是指编译前(编译预处理阶段),用定义中的值或者代码完全替换宏的标识符。
在gcc
中可以使用-E
或者--save-temps
,查看替换后的结果。
4. 编译预处理指令
以#
开头的都是编译预处理指令。除了宏定义,还有文件包含#include
和条件编译指令#if
、#ifdef
#ifndef
、#else
、#elif
。
- 文件包含
#include
把文件内容包含到代码中
- 条件编译指令
#if
、#ifdef
#ifndef
、#else
、#elif
根据编译条件,选择编译或者编译某段代码。
编译预处理指令不是C语言的成分,但是C语言程序离不开它们。