C语言笔记之宏定义

1. 宏定义是什么?

宏是用来表示一段代码的标识符。

宏也是标识符,也要满足标识符的规则。但通常习惯使用大写字母下划线命名。

2. 宏定义怎么用?

宏定义通常有三种用法:

  • 当作常量使用。
  • 当作函数使用。
  • 编译预处理。

2.1 宏定义常量

2.1.1 预定义宏

ANSI C标准定义有些定义好的宏定义,称为预定义宏。这些宏定义以双下划线__开头结尾。

No. 预定义宏 作用
1 __LINE__ 当前所在文件的行号
2 __FILE__ 表示当前源文件
3 __DATE__ 文件被编译的日期
4 __TIME__ 文件被编译的时间
  • 示例
printf("%s:%d\n",__FILE__,__LINE__);
printf("%s:%s\n",__DATE__,__TIME__);

在这里插入图片描述**注:**显示的时间为编译完成的时间,之后再运行程序,编译时间是不会改变的

2.1.2 自定义宏

除了使用标准定义的宏,可以使用#define指令用来定义一个宏。

  • 语法
#define 标识符 值
  • 示例
#define PI 3.1415926
  • 说明
  1. 注意没有结尾的分号,因为不是C的语句。
  2. 名字必须是一个单词,值可以是各种东西。
  3. 在C语言的编译器开始之前,编译预处理程序会把程序中的名字换成值。是完全的文本替换。
  4. 如果一个宏的值有其他宏的名字,也会被替换。
#define PI_2 2*PI

在这里插入图片描述

  1. 如果一个宏的值超过一行,最后一行之前行末需要加\。
//#define PI_2 2*PI
#define PI_2 2 \
             * \
             PI
  1. 宏的值后面出现的注释不会被当做宏的值的一部分。

2.2 带参数的宏

宏可以带参数,使用上有些像函数。这种宏称为带参数的宏。

  • 语法
#define 标识符(参数...) 代码
  • 示例
#define square(x) ((x)*(x))
#define cube(x) ((x)*(x)*(x))

是否可以不带括号?答案是否定的,参考如下代码
在这里插入图片描述

  • 说明
    上面因为缺少括号导致错误,称为宏定义边际效应,所以带参数的宏需要在一下两个位置加上括号:
  1. 参数出现的每个地方都要加括号。

  2. 整个值要加括号。

参数的宏也可以有多个参数

#define MIN(a,b) ((a)<(b)?(a):(b))

小例:

  1. 变量值交换SWAP(a,b)
#define SWAP(a,b) {int t=a;a=b;b=t;}
  1. 最大值MAX(a,b),最小值MIN()
#define MAX(a,b) ((a)>(b)?(a):(b))
#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. 宏展开

宏的本质是指编译前(编译预处理阶段),用定义中的值或者代码完全替换宏的标识符。
在这里插入图片描述在Linux下gcc中可以使用-E或者–save-temps,查看替换后的结果。

4. 编译预处理指令

#开头的都是编译预处理指令。除了宏定义,还有文件包含#include和条件编译指令#if#ifdef #ifndef#else#elif

  • 文件包含#include 把文件内容包含到代码中
  • 条件编译指令#if#ifdef #ifndef#else#elif

根据编译条件,选择编译或者编译某段代码。

发布了39 篇原创文章 · 获赞 4 · 访问量 697

猜你喜欢

转载自blog.csdn.net/weixin_44718794/article/details/103935671