news 2026/5/8 9:40:32

C语言预处理详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言预处理详解

目录

1、预定义符号

2、#define定义常量

3、#define 定义宏

4.带有副作用的宏参数

5.宏的替换规则

6.宏函数的对比

宏的优势:

宏的劣势:

7.命名习惯

8.移除宏的指令

9.条件编译

10.头文件


1、预定义符号

__FILE__ //进行编译的源文件

__LINE__ //文档当前的行号

__DATE__ //文档当前的日期

__TIME__ //文件被编译的时间

__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义

代码示例:

#include<stdio.h> int main() { printf("%s\n", __FILE__); printf("%d\n", __LINE__); printf("%s\n", __TIME__); printf("%s\n", __DATE__); return 0; }

运行结果:

2、#define定义常量

举个例子:

#define A 100

#define MAX 200

这个时候代码在运行的时候会自动把代码中的 A 的MAX替换成100和200

代码示例:

#include<stdio.h> #define A 100 #define MAX 200 int main() { int a = A; int c = MAX; printf("%d\n", a); printf("%d\n", c); return 0; }

运行结果:

3、#define 定义宏

#define 机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏

#define可以实现类似于函数的功能

宏的基本格式是:

#define 宏名(参数) 替换文本

代码示例:

#include<stdio.h> #define AQR(A) ((A)*(A)) int main() { int a = 10; int c = AQR(a); printf("%d\n", c); return 0; }

运行结果:

需要注意的这样的宏定义在使用的时候是非常容易出错的,比如刚才那段代码,如果这样写:

#include<stdio.h> #define AQR(A) A*A //把这里的括号去掉 int main() { int a = 10+1; int c = AQR(a); printf("%d\n", c); return 0; }

在程序中,预处理器会将其替换

#include<stdio.h> #define AQR(A) A*A int main() { int a = 10; int c = 10+1*10+1; printf("%d\n", c); return 0; }

这样的话运行结果就成了

很明显这不是我们想要的结果,所以为了避免这种情况,我们再进行宏定义的时候,最好在参数的两边加上括号

4.带有副作用的宏参数

当宏参数在宏定义中出现不止一次的时候,如果参数带有副作用,那么就会出现不可预期的结果。

例如:

#include<stdio.h> #define MAX(a,b) ((a) > (b) ? (a) : (b)) ; int main() { int x = 5; int y = 10; int z = MAX(x++, y++); printf("%d\n", z); printf("%d %d", x, y); return 0; }

这里经过预处理器处理之后:

z = ( (x++) > (y++) ? (x++) : (y++));

那么运行结果是怎样的呢?

分析一下计算过程:

首先进行x和y的大小比较,比较完成后x和y各自+1,在当前代码中x=5,y=10,比较结果是x>y,那么比较结果取后者,取完之后y再进行+1,所以最终的运行结果是x=6,y=12,z=11.

5.宏的替换规则

调用宏时,首先对参数进行检查,看看是否包含任何有#define的定义的符号,如果有首先先将其替换,

6.宏函数的对比

宏常用于简单的计算

宏的优势:

①由于宏的本质是文本的直接替换,不需要函数使用过程中的栈压等过程,所以宏相对函数,宏的运算速度比函数快。

②宏的参数是和类型无关的,函数只能在合适的类型的情况下使用

宏的劣势:

①由于宏的本质是文本的替换,所以宏的代码长度过长或者多次调用宏,会导致整的程序的代码长度大幅增加。

②容易出现运算优先级的问题

③无数据类型,不严谨

④无法调试

7.#和##运算符

7.1#运算符

#运算符可以将宏的参数“字符化”就是将这个参数变成字符串,并加上“”

举一个例子:

你想要打印,某某某是一个大帅哥

#include<stdio.h> #define PRINTF(name) printf(#name "shi yi ge da shuai ge \n") int main() { PRINTF(zhangsan); return 0; }

这个时候#name就被替换成了“name”

7.2##运算符

##可以把位于它两边的符号连接成一个符号,但不是简单拼接在一起,如有有一个符号,原本是宏参数,那么拼接之后还是宏参数,还是会被替换

举个例子,利用宏生成适用于各种类型的add函数

#include<stdio.h> #define TYPEADD(type) type##add(type a,type b){\ return a + b;\ } TYPEADD(int); int main() { int c = intadd(20, 30); printf("%d", c); return 0; }

运行结果:

7.命名习惯

宏的命名习惯是宏的名字全部大写

8.移除宏的指令

#undef name

如果你想要重新定一个相同名字的宏,你需要先把原来的宏移除

#define MAX 100 #undef MAX #define MAX 200

9.条件编译

if 条件语句相似

#if //如果

#elif //否则

#endif //结束条件编译

#ifdef //如果被宏定义过,为真,执行下面的代码

10.头文件

头文件的包含一般分为两种,一种是用双引号包含,如:#include”stdio.h“.一种是"<>"包含,如:#include<stdio.h>

用""包含的头文件有两种途径,先去源文件目录里面查找,即你自己写的头文件,然后再去库函数头文件里查找

而<>包含的头文件直接在,库函数头文件里查找

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 9:40:30

魔兽争霸3优化神器:5个简单步骤让你的经典游戏焕然一新

魔兽争霸3优化神器&#xff1a;5个简单步骤让你的经典游戏焕然一新 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在现代电脑上的各种…

作者头像 李华
网站建设 2026/5/8 9:33:46

飞书文档批量导出终极指南:700+文档25分钟快速备份方案

飞书文档批量导出终极指南&#xff1a;700文档25分钟快速备份方案 【免费下载链接】feishu-doc-export 飞书文档导出服务 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 你是否担心飞书文档数据丢失&#xff1f;是否苦恼于文档迁移的繁琐操作&#xf…

作者头像 李华
网站建设 2026/5/8 9:33:36

Sorbetto:为Ruby开发者打造的VS Code增强插件,提升Sorbet开发体验

1. 项目概述&#xff1a;Sorbetto&#xff0c;一个为Ruby开发者量身打造的VS Code增强插件 如果你是一名Ruby开发者&#xff0c;并且正在使用VS Code作为主力编辑器&#xff0c;那么你很可能已经对Sorbet——那个由Stripe开发的强大静态类型检查器——有所耳闻。Sorbet为Ruby这…

作者头像 李华
网站建设 2026/5/8 9:32:27

高德xck、in算法分析

声明cp execjs.compile(open(1.js,r,encodingutf-8).read()) result cp.call(getN,data) print(result) params {......................,"xck_channel": "default","xck": result[_0x4ca5c43994][xck],"_bx-m": "1" } d…

作者头像 李华
网站建设 2026/5/8 9:31:52

MANTIS:基于Android的本地AI代理,实现手机自动化任务执行

1. 项目概述&#xff1a;一个运行在你手机里的“数字管家” 如果你和我一样&#xff0c;对手机上那些号称“智能”的语音助手感到失望——它们要么只能回答简单问题&#xff0c;要么就是把你引向一个网页搜索——那么MANTIS的出现&#xff0c;可能会彻底改变你的看法。这不是一…

作者头像 李华
网站建设 2026/5/8 9:31:51

用DS1302给51单片机做个电子钟,手把手教你从接线到调校(附完整代码)

用DS1302给51单片机打造高精度电子钟&#xff1a;从硬件搭建到软件调校全指南 第一次接触电子钟项目时&#xff0c;我被那个小小的DS1302芯片深深吸引——它能在断电后依然保持时间走动&#xff0c;还能用普通的32.768kHz晶振实现日误差不超过2秒的精度。本文将带你完整实现一个…

作者头像 李华