C语言从头学43——预处理指令(二)

本文继续学习预处理指令,并延续前文编号。

三、预处理指令 #undef

有时想定义一个宏,但不记得以前是否使用过,如重复定义且定义内容不同,会报错。此时可以先使用 #undef 命令取消这个宏名;即使取消一个不存在的宏名也无所谓,系统也不会报错。

格式:#undef 宏名

四、预处理指令 #include

这是一个已经使用过多次的预处理命令,作用是编译时将其它源码文件,加载进入当前文件。习惯上我们称这个命令操作为包含某头文件。

格式1:#include <*.h> //加载系统提供的文件用尖括号

格式2:#include "*.h" //加载自己写的文件引号

说明:多个#include语句无顺序要求;重复包含也不会报错。

五、预处理指令 #if...#endif

#if ... #endif指令用于预处理的条件判断,满足条件时,内部的行会被编译,否则就被编译器忽略。该语句中间还可以加上#else,形成#if ... #else ... #endif结构 (见举例程序)

六、预处理指令 #ifdef...#endif

#ifdef...#endif 指令用于判断某个宏是否定义过。为了避免源码文件可能重复加载某个头文件,可以在头文件里使用 #define 命令定义一个空的宏。在需要加载处通过#ifdef...#endif语句检查这个宏,判断头文件是否被加载了。如未加载,可以配合使用#else予以加载。

七、预处理指令 #ifndef...#endif

#ifndef...#endif指令与第六条介绍的指令正好相反。它用来判断,如果某个宏没有被定义过,则执行指定的操作。这条语句常用来防止重复加载。使用的方法同上,还是需要在头文件中加一个空宏做为标记,再用本条指令检查这个宏,如不存在,则予以加载。

八、预定义宏

C语言提供一些预定义好的宏,可以直接使用,比如前边学习过的代表不定参数的宏__VA_ARGS__;其它的诸如:

DATE :编译日期,格式为"Mmm dd yyyy"的字符串(比如 Nov 23 2021)。

TIME :编译时间,格式为"hh:mm:ss"。

FILE :当前文件名。

LINE :当前行号。

func :当前正在执行的函数名。该预定义宏必须在函数作用域使用。

九、预处理指令#line

#line指令用于重置预定义宏 LINE ,将其改为自定义的行号。后面的行自定义行号开始开始计数。

#line 200 //将当前行的行号重置为 200

十、预处理指令#error

#error指令用于让预处理器抛出一个错误,终止编译。

#if INT_MAX < 100000

#error int type is too small

#endif

十一、与上述内容相关的小程序

cpp 复制代码
#include<stdio.h>
void test()
{
#define TEST 1
}
int main(void)
{
//预处理指令#undef的使用
#define MAX 1000
    printf("MAX=%d\n", MAX);
#undef MAX
    //printf("MAX=%d", MAX);
    //用#undef指令取消MAX宏后,如再使用该宏会报错
//预处理指令#if...#else...#endif的使用
#ifdef MAX //MAX是否定义
    printf("已定义的宏MAX=%d\n", MAX);
#else
#define MAX 10000 //如未定义重新定义
    printf("重新定义的MAX=%d\n", MAX);
#endif
//预处理指令#ifndef...#endif的使用
#ifndef TEST
    printf("未发现函数test()...\n"); //这条语句不会执行,因为宏TEST已在test()定义
#endif
//显示C语言中常用预定义宏
    printf("%s\n", __DATE__); //运行结果:Aug  6 2024
    printf("%s\n", __TIME__); //运行结果:19:37:15
    printf("%s\n", __FILE__); //运行结果:D:\C语言从头学\C语言从头学43.c
    printf("%d\n", __LINE__); //运行结果:75
    printf("%s\n", __func__); //运行结果:main
//#line的使用
#line 1000
    printf("%d\n", __LINE__); //运行结果:1000
//#error的使用
#define INT_MAX 10000
#if INT_MAX < 100000
   //#error int type is too small //不需等到编译,编程过程即报错
#endif

    getchar();
    return 0;
}
相关推荐
草莓熊Lotso6 小时前
Linux 基础 IO 初步解析:从 C 库函数到系统调用,理解文件操作本质
linux·运维·服务器·c语言·数据库·c++·人工智能
梵刹古音6 小时前
【C语言】 字符数组相关库函数
c语言·开发语言·算法
2601_9491465312 小时前
C语言语音通知API示例代码:基于标准C的语音接口开发与底层调用实践
c语言·开发语言
学嵌入式的小杨同学12 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
Aaron158813 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理
爱编码的小八嘎14 小时前
C语言对话-21.模板特化,缺省参数和其他一些有趣的事情
c语言
yueyuexiaokeai116 小时前
linux kernel常用函数整理
linux·c语言
想放学的刺客17 小时前
单片机嵌入式试题(第29期)嵌入式系统的电源完整性设计与去耦电容选型。抗干扰设计与EMC合规性
c语言·stm32·嵌入式硬件·物联网·51单片机
集芯微电科技有限公司19 小时前
15V/2A同步开关型降压单节/双节锂电池充电管理IC支持输入适配器 DPM 功能
c语言·开发语言·stm32·单片机·嵌入式硬件·电脑
zz34572981131 天前
c语言基础概念9
c语言·开发语言