尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C语言——预处理器
基本介绍预处理指令预处理过程中会执行预处理指令预处理指令以 # 号开头用于指导预处理器执行不同的任务。预处理指令的特点1预处理指令应该放在代码的开头部分。2预处理指令都以 # 开头指令前面可以有空白字符比如空格或制表符# 和指令的其余部分之间也可以有空格但是为了兼容老的编译器一般不留空格3预处理指令都是一行的除非在行尾使用反斜杠将其折行。4预处理指令不需要分号作为结束符指令结束是通过换行符来识别的。5预处理指令通常不能写在函数内部有些编译器的扩展允许将预处理指令写在函数里但强烈不建议这么干。宏定义#define宏定义#define 宏名称 替换文本宏名称满足标识符规范建议使用大写在预处理阶段所有的宏名称会被替换成对应的替换文本预处理阶段宏定义直接文本替换PI1→3.14const在运行时创建常量#include stdio.h // 1. 使用宏定义定义常量 #define PI1 3.14 // 2. 使用宏定义给数据类型取别名 #define BOOL int // 3. 替换文本还可以是表达式或者语句 #define EX 200 / 2 78 #define DN int n 100; // 4. 替换文本中还可包含其他宏名称 #define PEX printf(%d\n, EX) //------------------------------------------- //宏定义取消之前是可以使用的 // 取消宏定义 //#undef PI1 //------------------------------------------- // 使用const定义常量 const double PI2 3.15; // typedef 数据类型别名 typedef unsigned long long U64; #define 整型 int #define 浮点 double #define 如果 if #define 否则 else #define 打印 printf int main(void) { printf(PI1 %.2lf\n, PI1); printf(PI2 %.2lf\n, PI2); BOOL n1 1; U64 n2 100; printf(n1%d,n2%lld\n, n1, n2); int n3 EX; printf(n3%d\n,n3); DN printf(%d\n,n); PEX; // 中文编程 ------------------------------ 整型 年龄 18; 如果 (年龄 18) { 打印(欢迎光临); } 否则 { 打印(请在家长陪同下访问); } return 0; }取消宏定义#undef 宏名称带参数的宏定义#define 宏名称(形参列表) 可以包含形参的替换文本// 带参数的宏定义 返回两个数中较大的 #define MAX(a,b) a b ? a : b // 带参数的宏 定义计算平方 替换文本中的参数一般建议使用小括号括起来 #define SQ1(n) n * n #define SQ2(n) (n) * (n) // 带参宏定义 实现立方计算 #define CUBE(n) (n)*(n)*(n) int main() { printf(较大的数%d \n, MAX(108, 67)); // 替换为 printf(较大的数%d \n, 108 67 ? 108 : 67); printf(平方: %d \n, SQ1(43)); // 替换为: printf(平方: %d \n, 43 * 43); printf(平方: %d \n, SQ2(43)); // 替换为printf(平方: %d \n, (43) * (43)); }文件包含#include包含标准库头文件#include 头文件名包含自定义头文件#include 头文件路径1. 相对路径 目标文件头文件在当前文件源文件的同级或者下级路径以 ./ 开头./ 可以省略 目标文件头文件在当前文件源文件上级、更上级或者需要先去到上级目录路径以 ../ 开头 ../ 表示上一级目录 ../../ 表示上上极目录 ../../../ 表示上上上级目录 2. 绝对路径 目标文件在计算机上绝对的位置类 Unix 系统中的路径使用/ windows 系统的路径中使用\或/。/*********************************************************** 目录结构 ├─ 03-include-example │ ├─ myheader05.h │ └─ project │ ├─ inc │ │ └─ myheader04.h │ ├─ myheader03.h │ └─ src │ ├─ includes │ │ └─ myheader02.h │ ├─ main.c │ └─ myheader01.h ***********************************************************/ #include stdio.h // 目标文件在同级 // #include ./myheader01.h #include myheader01.h // 目标文件在下一级 // #include ./includes/myheader02.h #include includes/myheader02.h // 目标文件在上一级文件夹 #include ../myheader03.h // 找到目标文件需要先去到上一级 #include ../inc/myheader04.h // 目标文件在上上级 #include ../../myheader05.h // 使用绝对路径 // #include E:\SH240905\Code\Chapter15\03-myheader.h #include E:\vsCode\code\sggtest\chapter\chapter15\03-myheader.h //写成斜杠/和反斜杠\都可以 int main() { func01(); func02(); func03(); func04(); func05(); func(); return 0; }条件编译#if① #if单向分支#if 条件 #endif双向分支#if 条件 #else #endif预处理完之后只留下满足条件的那一部分多向分支#if 条件 #elif 条件 #elif 条件 #else #endif② #if defined判断是否定义了宏名称定义了才成立单向分支#if defined 宏名称 #endif双向分支#if defined 宏名称 #else #endif多向分支#if defined 宏名称 #elif defined 宏名称 #elif defined 宏名称 #else #endif③ #ifdef就是#if define的简写单向分支#ifdef 宏名称 #endif双向分支#ifdef 宏名称 #else #endif④ #ifndef判断是否定义了宏名称没有定义了才成立其中的n可以记作not单向分支#ifndef 宏名称 #endif双向分支#ifndef 宏名称 #else #endif条件编译所涉及的预处理器指令#if #ifdef #ifndef #if defined #else #elif #endif条件编译应用案例根据操作系统不同包含不同的头文件/*********************************************************** * 1Windows平台下的暂停函数的原型是 void Sleep(DWORD dwMilliseconds)参数的单位是“毫秒”位于 windows.h 头文件。 * 2Linux平台下暂停函数的原型是 unsigned int sleep (unsigned int seconds)参数的单位是“秒”位于 unistd.h 头文件。 * (3) windows平台通常会预先定义宏常量 _WIN32 linux 平台通常会预先定义宏常量 __linux__ ***********************************************************/ #include stdio.h #ifdef _WIN32 #include windows.h #define SLEEP(t) Sleep(t*1000) #define PLAYFORM windows #elif __linux__ #include unistd.h #define SLEEP sleep #define PLAYFORM Linux #endif int main(void) { printf(program start .... \n); //暂停5s SLEEP(5); //打印 printf(Hello,%s\n,PLAYFORM); // 条件分支 ------------------------------------ int num 600; if (100 num) { printf(100更大! \n); } else { printf(100更小! \n); } // 预处理指令 条件编译----------------------------- #if 100 num printf(100更大! \n); #else printf(100更小! \n); #endif return 0; }解决头文件重复包含的问题问题现象当同一个头文件被多次包含时会导致函数或变量的重复定义错误产生原因预处理指令#include会将头文件内容直接插入源文件多次包含意味着多次插入相同内容常见场景项目结构复杂时头文件可能被间接包含多次如A.h包含B.h同时源文件也直接包含B.h保护机制标准库使用条件编译防止重复包含工作原理第一次包含时_INC_HEADERNAME未定义执行#define并包含内容后续包含时因宏已定义跳过全部内容命名规则标准库通常使用__头文件名大写形式__如_INC_STDIO这样子就解决的头文件重复包含的问题了
RELATED

相关推荐

三极管BJT工作原理与工程实践:从PN结到开关放大电路选型排错

三极管BJT工作原理与工程实践:从PN结到开关放大电路选型排错

三极管(BJT)这个老元件,很多工程师“会用不会讲”,本文从原理到选型、从开关到放大、从公式到排错,系统拆解NPN/PNP三极管的工作机制与工程落地方法,读完你就知道为什么VBE是0.7V、为什么饱和不能硬套β、以…

📅 2026/10/6 18:31:23
三、LangChain调用大语言模型、聊天模型和文本嵌入模型

三、LangChain调用大语言模型、聊天模型和文本嵌入模型

一、LangChain调用大语言模型 1. 简介 现在市面上的模型多如牛毛,各种各样的模型不断出现,LangChain模型组件提供了与各种模型的集成,并为所有模型提供一个精简的统一接口。 LangChain目前支持三种类型的模型: LLMs(大语言模型…

📅 2026/10/6 7:02:10
LeetCode高效刷题指南:掌握核心算法模式与系统化训练方法

LeetCode高效刷题指南:掌握核心算法模式与系统化训练方法

你有没有过这样的经历:打开 LeetCode,面对上千道题目,从哪开始刷?刷到什么程度才算够?刷完一遍,过两周再看到同类题,思路又卡壳了?这几乎是每个技术人准备面试、提升算法能力时都会遇…

📅 2026/9/8 1:43:19
MORE NEWS

更多资讯

📰

GEO从入门到实操:让AI搜索引用你的独立站

最近这半年,我把几乎所有研究搜索流量的空余时间,都压在了一个叫GEO的东西上。GEO不是某个冷门的证书,它的全称是Generative Engine Optimization,生成式引擎优化。说白了就一件事:怎么让AI搜索把你当成可靠的答案来源…

📰

Compose vs XML:Android声明式UI迁移实战指南

说实话,看到“A2UI”这个词的时候我愣了一下,后来反应过来,这不就是我们天天挂在嘴边的 Jetpack Compose 嘛——Android 官方原生推出的声明式 UI 框架。说句掏心窝的话,我从 2018 年就开始在个人项目里折腾 Compose 的预览版&…

📰

智能体架构设计:核心组件与实战优化指南

1. 智能体架构公式:从理论到实践的完整指南在AI技术快速发展的今天,智能体(Agent)架构已经成为构建复杂AI系统的核心框架。不同于传统的程序化开发,智能体架构赋予了系统自主感知、决策和执行的能力。我曾在多个实际项目中应用不同架构的智能…

📰

航天器追逃博弈中的EKF与纳什均衡技术解析

1. 项目背景与核心问题航天器末端追逃博弈是空间对抗领域的关键课题,其本质是双方在有限时间和空间内进行的动态策略对抗。传统完全信息博弈假设在实际战场环境中往往难以成立,因为作战双方无法实时获取对手的完整状态信息。这正是我们研究的核心价值所在…

📰

微信小程序UI重塑:打造一键出图到代码融合的可视化工具链

微信小程序经过VIBE CODING快速搭完第一版后,迎面而来的就是UI重塑问题。大多数人和我一样,对着微信开发者工具里的原生代码,想要调整一套符合预期的界面,却不知道从哪下手。我干脆做了个全程可视化工具,把一键出图、自…

📰

Java工程师LangChain4j实战:RAG问答系统从设计到落地

1. 为什么 Java 工程师现在该认真看看 LangChain4j这两年大模型应用开发的热度不用我多说,但如果你是一个写了五六年 Java 的后端,打开各种教程一看全是 Python,心里多少有点不是滋味。LangChain4j 就是在这个背景下冒出来的东西——它是 Lan…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬