前言
本章总结归纳宏以及其他指令的使用。
C语言 | 快速了解C的发展史🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 指针、数组 一文透彻~~~🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 结构体、联合、枚举🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 声明🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 作用域 在也不用担心分不清变量的作用域拉!!!🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 编译步骤 会用C还不知道C如何编译???🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 数据类型总结🧡💛💚💙
C语言 | 【耗费一夜总结三本C语言系列】之 位及进制的用法🧡💛💚💙
文章目录
一、预处理器啊🤍
预处理器会在程序运行前,事先查看程序的中的预处理命令;
- 删除注释、插入被#include指令包含的文件的内容;
- 定义和替换由#define指令定义的符号;
- 确定代码的部分内容是否应该根据一些条件编译指令进行编译;
1.1 编译程序的第一个步骤
- 编译器会将源代码中出现的字符映射到源字符集;
- 编译器定位为每个反斜杠后跟着换行符的实例(物理行),并删除它们,转换成一个逻辑行;
- 再把文本分成将预处理记号、空白序列、注释序列;
1.2 预定义符号
__FILE__
:进行编译的源文件名;__LINE__
:文件当前行的行号;__DATE__
:文件被编译的日期;__TIME__
:文件被编译的时间;__STDC__
:若编译器遵循ANSIC时为1,否则未定义;__STDC_HOSTRD__
:本机环境设置为1,否则为0;
二、宏💜
2.1 #define
- #为一行的开始,且与指令之间不能有空格;
- 可存在于任何位置,从定义到末尾都有效;
- 不可以出现在递归;
宏定义:
使用#define创建宏;
宏展开:
从宏最终编程替换文本的过程;
2.2 重定义常量
当一个常量被定义后,又被定义;
- 只有新定义和旧定义相同才允许重定义;
- 相同指记号、顺序相同;
2.3 #运算符
将记号转换为字符串;
#define PPRINTF(F) printf("the test:" #F "\n")
PPRINTF("test") => the test:"test"
PPRINTF(22) => the test:22
2.4 ##运算符
用于类函数宏的替换部分,将两个记号组合成一个记号;
#define TEXT(n) x ## n;
TEXT(2) => x2
2.5 变参宏...
C99提供了这样的工具,把宏参数列表中后的参数写成省略号;
#define PPRINT(F, ...) printf("[INFO] " #F ": " __VA_ARGS__)
int y = 109;
PPRINT(22, "It is num: %d", y) => [INFO] 22: It is num: 109
/*
F 对应参数 22
__VA_ARGS__:对应 "It is num: %d", y
*/
2.6 宏与函数
在某些情况下宏的使用比函数在程序中规模和速度方面会加高效;
- 例如在嵌套循环中使用;
- 速度快但空间使用增加,需要将文本替换;
三、头文件🧡
3.1 #include
当预处理器发现#include时,会查看后面的文件名并把文件的内容包含到当前文件;
- 大型的头文件不一定显著增加程序的大小;
使用头文件:
- 明示常量;
- 宏函数;
- 函数声明;
- 结构模板定义;
- 类型定义;
四、其他指令💛
4.1 #undef指令
取消已定义的#define指令,若未定义,则该命令仍有效;
4.2 #ifdef、#else、#endif指令
不使用
{}
;
#ifdef(#idndef) 常量
....
#else
....
#endif
4.3 防止多次包含一个文件
#ifndef 文件名_H_
#defien 文件名_H_
....
....
#endif
4.4 #if、#elif
#if 常量表达式
....
#elif 常量表达式
....
#else
....
#endif
4.5 #line、#error
#line
:指令重置__LINE__
和__FILE__
宏报告的行号和文件名;
#line 行号 "文件名"
#error
:让预处理器发出一个错误信息;
#error 错误信息
4.6 #pragma
把编译器指令放入源代码;
- 可控制分配给自动变量的内存量;
- 设置错误检查的严格程度;
- 启用非标准语言特性;