文章目录
article
预处理器
AI文章摘要
gemini-2.0-flash-lite
这篇文章介绍了C语言中的预处理器指令,主要包括include、define和ifdef指令。
include指令用于将指定文件内容包含到当前文件中,其中<headerfile.h>用于查找系统头文件库,而"headerfile.h"则优先在工作目录查找。
define指令可用于声明宏常量和宏函数。宏常量在预处理时会被替换为相应的值,常用的内置宏常量有__FILE__(当前文件路径)、__LINE__(当前行号)、__TIME__(编译时间)和__DATE__(编译日期)。使用宏常量时,其名称应大写以区分普通变量,且支持定义包含已有宏常量的表达式。宏函数并非真正的函数,而是在预编译阶段将使用它的地方按表达式展开。offsetof是一个常用的宏函数,用于计算结构体成员变量的偏移值。
ifdef指令用于条件编译,根据某个宏定义是否存在来决定是否编译某段代码。
文章还提到了预处理常用的技巧,如通过宏定义控制日志打印的开关。
最后,介绍了Visual C++编译器的一些常用宏指令,如_CRT_SECURE_NO_WARNINGS和#pragma warning(disable:4996),用于处理特定的编译警告。
预处理器指令
include指令
include指令用于将指定文件中的内容包含到本文件.
#include<headerfile.h> //gcc中只会查找系统头文件库(一般/usr/include、/usr/local/include)
#include"headerfile.h" //gcc会从工作目录中查找, 然后再从系统头文件库中找.
define指令
define指令可以声明宏常量以及宏函数.
- 宏常量: 宏常量预处理时都转为相应的值,编译器看不到这个变量名
- 常用的内置宏常量.
__FILE__替换成一个字符串, 内容是当前文件的路径__LINE__替换成一个整形 ,内容表示这个宏出现的行,常用在错误编译错误输出__TIME__替换成字符串, 内容是编译的时间__DATE__替换成字符串,内容是编译的日期
- 注意事项
- 将名称替换成后面的值
- 支持含有已经定义的宏常量的表达式.
- 例如已经定义PX , PY .那么可以定义#define OO PX*PY
- 宏常量名应该大写,区分普通变量
- 常用的内置宏常量.
- 宏函数不是真正的函数, 它在预编译阶段对使用到宏函数的地方按表达式展开
- 常用宏函数: 一些标准的宏函数封装在stddef.h中
- offsetof(structName, structMember);结构体成员变量偏移值函数
- 第一个参数是结构体完整的名字:struct 结构体名//注意:没有结构体名字的不能使用该宏函数
- 第二个参数是成员变量名字
- 注意: 宏函数近在预编译阶段展开处理, 展开后可能导致结合顺序的改变
- offsetof(structName, structMember);结构体成员变量偏移值函数
- 注意事项
- 常用宏函数: 一些标准的宏函数封装在stddef.h中
//宏常量定义
#define marcoName valjue
#undefine marcoName
//宏函数定义
#define marcoFunc(arg1,arg2,...) expression //例如#define SUM(x , y) ((x)+(y))
ifdef指令
ifdef指令条件编译
//格式1, 如果已经定义或者存在,那么编译1代码, 如果没定义那么就编译2 代码
#ifdef 某个宏定义名
...
#else
...
#endif
//格式2, 和格式1的逻辑相反
#ifdef 表达式
...
#else
...
#endif
//通过#ifdef 0 #endif可以实现注释功能
预处理常用的技巧
打印日志
#ifndefin _LOG
#define _LOG() logfunction()
#else
#define _LOG()
#endif
//这种思路是通过_LOG标志来控制_LOG()宏函数的定义, 从而控制_LOG()的行为. 空的_LOG()宏函数定义将删除代码中所有的日志打印
visual C编译器的常用宏指令
- #define _CRT_SECURE_NO_WARNINGS放在程序第一行 处理由C语言函数的警告操作:
- #pragma warning(disable:4996)忽略vc警告