C语言之预处理
预处理
- 一.头文件的包含
- 1.1头文件的作用
- 1.2包含头文件的方式
- - 包含标准库头文件
- - 包含用户自定义头文件
- 1.3嵌套文件包含
- 二.条件编译
- 2.1条件编译的作用
- 2.2条件编译的指令
- 三.预定义符号
- 四.define
- 4.1define定义常量
- 4.2#define定义宏
- 4.2.1定义宏时常见错误
- 4.3宏替换的规则
- 4.4带有副作用的宏参数
- 4.5宏与函数对比
- 4.6#undef
- 五.#和##运算符
一.头文件的包含
1.1头文件的作用
头文件的主要作用是提供函数声明、宏定义、数据类型定义和全局变量声明等。它允许程序员将代码的接口部分与实现部分分离,从而实现模块化编程。常见的头文件用途包括:
- 函数声明:声明函数的原型,使得函数可以在其他文件中被调用。
- 宏定义:提供全局的宏定义,用于代码的简化和优化。
- 数据类型定义:定义结构体、枚举类型等,方便代码的复用。
- 全局变量声明:声明全局变量,使得变量可以在多个文件中共享。
1.2包含头文件的方式
- 包含标准库头文件
#include <文件名>
特点:
- 用于包含系统标准库头文件(如<stdio.h>、<stdlib.h>等)。
- 预处理器会在系统的标准库目录中查找头文件。
- 不需要指定路径,也不需要引号。
- 包含用户自定义头文件
#include "文件名"
特点:
- 用于包含用户自定义的头文件。
- 预处理器会先在当前源文件所在的目录查找头文件,如果找不到,再在系统的标准库目录中查找。
- 需要使用双引号"",并且可以指定相对路径或绝对路径。
1.3嵌套文件包含
当头文件被多次包含时,同时会被编译多次,此时编译的压力较大;为防止这种情况,可以用到条件编译。
二.条件编译
2.1条件编译的作用
条件编译的主要作用是根据预定义的条件(如宏定义、编译器选项等)来决定是否编译某段代码。可用于一下场景:
- 多平台兼容性:根据不同的操作系统或平台编译特定代码。
- 调试与发布模式:在调试模式下启用调试信息,在发布模式下关闭调试信息。
- 功能模块的选择:根据编译选项启用或禁用某些功能模块。
- 避免重复定义:通过条件编译防止头文件的重复包含。
2.2条件编译的指令
- #if、#else、#elif 和 #endif
这些指令用于根据条件表达式的值选择性编译代码。
#if:如果条件表达式为真(非零),则编译其后的代码。
#elif:如果前面的#if或#elif条件不满足,而当前条件为真,则编译其后的代码。
#else:如果前面的所有条件都不满足,则编译#else部分的代码。
#endif:结束条件编译块。
这里#if、#else、#elif 和 #endif可用于嵌套指令。
- #ifdef 和 #ifndef
这两个指令用于检查某个宏是否被定义。
#ifdef:如果宏被定义,则编译其后的代码。
#ifndef:如果宏未被定义,则编译其后的代码。
三.预定义符号
C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。
__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
使用示例:
printf("file:%s line:%d\n", __FILE__, __LINE__);
四.define
define基本语法:
4.1define定义常量
#define name stuff
在使用define定义常量时,最好不要在结尾加上分号,否则会造成一系列问题。
就以下面代码为例:
if( )max = MAX;
elsemax = 0;
如果是加了分号的情况,等替换后,if和else之间就是2条语句,⽽没有⼤括号的时候,if后边只能有⼀条语句。这⾥会出现语法错误。
4.2#define定义宏
#define机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏(define macro)。
#define name( parament-list ) stuff
4.2.1定义宏时常见错误
举例:
#define SQUARE( x ) x * xint a = 5;
printf("%d\n" ,SQUARE( a + 1) );
刚看这段代码,很多人会误解为结果是36,但正确结果却是11.这是因为,替换文本时,参数x被替换成a+1,所以这条语句实际上变成了:
printf ("%d\n",a + 1 * a + 1 );
要想解决这个问题,就要在宏定义是多加上几个括号:
#define SQUARE(x) (x) * (x)
printf ("%d\n",(a + 1) * (a + 1) );
再看下一个例子:
#define DOUBLE(x) (x) + (x)
int a = 5;
printf("%d\n" ,10 * DOUBLE(a));
看上去,好像打印100,但事实上打印的是55.
宏替换之后结果是:
printf ("%d\n",10 * (5) + (5));
由于乘法在前,所以结果是55.
要解决这个问题,在最外层加一对括号。
#define DOUBLE( x) ( ( x ) + ( x ) )
4.3宏替换的规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
-
在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先
被替换。 -
替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。
-
最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上
述处理过程。
注意:
- 宏参数和#define定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
- 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
4.4带有副作用的宏参数
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8;
z = MAX(x++, y++);printf("x=%d y=%d z=%d\n", x, y, z);
这里a,b都会替换为x++和y++,而在运行时,会造成x和y的自增,导致想要的结果与实际输出不符,在自己使用时,要尽量避免使用这类代码。
4.5宏与函数对比
4.6#undef
这条指令⽤于移除⼀个宏定义。
#undef NAME
//如果现存的⼀个名字需要被重新定义,那么它的旧名字⾸先要被移除
五.#和##运算符
#运算符
#运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。
#运算符所执⾏的操作可以理解为”字符串化“。
例如:
#define PRINT(n) printf("the value of "#n " is %d", n);
当把a作为n的参数输入时,结果为下
printf("the value of ""a" " is %d", a);
##运算符
##可以把位于它两边的符号合成⼀个符号,它允许宏定义从分离的⽂本⽚段创建标识符。 ## 被称为记号粘合
这样的连接必须产⽣⼀个合法的标识符。否则其结果就是未定义的。
相关文章:
C语言之预处理
预处理 一.头文件的包含1.1头文件的作用1.2包含头文件的方式- 包含标准库头文件- 包含用户自定义头文件 1.3嵌套文件包含 二.条件编译2.1条件编译的作用2.2条件编译的指令 三.预定义符号四.define4.1define定义常量4.2#define定义宏4.2.1定义宏时常见错误 4.3宏替换的规则4.4带…...
AcWing--869.试除法求约数
题目: 给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数 n。 接下来 n 行,每行包含一个整数 ai。 输出格式 输出共 n 行,其中第 i 行输出第 i 个整数 ai 的所有…...
【HeadFirst系列之HeadFirstJava】第16天之深入解析 Java 集合与泛型:高效管理数据的终极指南!(含代码实战)
Java 集合与泛型全解析:数据结构的奥秘(基于 Head First Java 第 16 章) 在 Java 开发中,我们经常需要存储和操作大量数据。如何高效地存储、检索和操作数据?如何避免数组的局限性?Java 集合框架ÿ…...
【从零开始学习计算机科学】操作系统(七)文件管理
【从零开始学习计算机科学】操作系统(七)文件管理 文件管理文件的逻辑结构文件的读写方式文件的物理结构与组织文件目录空闲块管理文件的共享文件的权限控制与保护文件系统的其他功能文件管理 文件管理主要涉及文件的逻辑组织和物理组织,目录的结构和管理。所谓文件管理,就…...
Stable Diffusion F.1模型全面解析
一、引言:生成式AI的变革与SD模型的演进 生成式AI的崛起 扩散模型(Diffusion Model)成为图像生成领域的主流范式,其通过逐步去噪过程实现高保真图像合成。Stable Diffusion(SD)作为开源社区标杆,…...
基于SpringBoot的手机销售网站设计与实现(源码+SQL脚本+LW+部署讲解等)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
上海利氪科技-再次续订MappingSpace
2024年6月,智能底盘系统方案商利氪科技完成C轮融资,本轮融资规模超10亿元人民币。 成立于2021年,利氪科技短短三年时间就已获得近20亿元融资。 利氪科技是领先的智能线控底盘系统方案商。公司聚焦新能源汽车和自动驾驶核心领域,依…...
go注册rpc接口
1.定义proto文件: syntax "proto3";package pb;service Service { rpc RPC (Request) returns (Reply) {} }message Request {string Action 1;int64 TraceID 2;string Payload 3; }message Reply {int32 Code 1;int64 TraceID 2;string Pa…...
如何在Spring Boot中校验用户上传的图片文件的两种方法
在现代应用中,用户上传图片是一个常见的需求。无论是社交平台、电子商务网站还是任何需要用户交互的应用,图片上传功能都显得尤为重要。但合理地校验用户上传的图片文件是必不可少的步骤,避免不合规的文件影响系统的稳定性和安全性。本文将介…...
如何将一个项目推送到gitlab
1. 初始化本地项目为 Git 仓库 若本地项目还不是 Git 仓库,要先将其初始化为 Git 仓库。在项目根目录下打开终端,执行如下命令: git init 2. 添加文件到暂存区 使用 git add 命令把项目中的文件添加到暂存区。若要添加所有文件࿰…...
【JavaWeb学习Day24】
Web前端实战 Vue工程化 Vue是一款用于构建用户界面的渐进式的JavaScript框架。(官方:https://cn.vuejs.org) Vue项目工程化:在企业级的前端项目开发中,把前端开发所需求的工具、技术、流程、经验等进行规范、标准化。…...
Scratch034豌豆发射(下)
知识回顾 1、克隆体点击角色的判断 2、使用克隆体时“停止该角色其他脚本”积木的作用范围。 效果演示 提示:这里可以添加本文要记录的大概内容每隔一段时间,舞台右侧就会出现多个除草机向左移动 点击不同位置的豌豆射手,可以发射豌豆攻击对应位置的除草机 除草机被豌豆击中…...
nacos下载及安装
下载官方最新稳定版 github下载较慢,推荐下面的下载链接 Nacos Server 下载 | Nacos 官网 点击下载和试用下载最新稳定版 Nacos Server 下载 | Nacos 官网 配置检查(可选) 默认情况下,Nacos 使用内置的 Derby 数据库&#x…...
javase集合框架Map篇
一、常见的Map的实现 有HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap。 二、HashMap和Hashtable 的区别 HashMap:底层是基于数组链表,非线程安全的,默认容量是16、允许有空的健和值。 Hashtable:基于哈希表…...
【RAGFlow】windows本地pycharm运行
原因 由于官方只提供了docker部署,基于开源代码需要实现自己内部得逻辑,所以需要本地pycharm能访问,且docker运行依赖得其余组件,均需要使用开发服务器得配置。 修改过程 安装python 项目依赖于Python 版本:>3.1…...
STM32初始安装
前言 很多人刚买来STM32就迫不及待地想要用它来写程序,看见STM32开发版和ST-Link上有几个插口就直接连接,结果就像我一样一不小心就导致ST -Link烧坏了😂 所以本篇博客将做最基础的但是对于小白来说最重要的教学,STM32的线路连接…...
数据库系统概论(二)数据模型
数据库系统概论(二)数据模型 数据库系统概论(二)数据模型前言一、数据建模二、概念模型三、数据模型的三要素四、层次模型五、网状模型六、关系模型 总结(核心概念速记): 数据库系统概论&#x…...
深入理解C语言链表:数据结构的基石
在C语言的编程宇宙中,链表就像是一座稳固的基石,支撑着众多复杂程序的构建。它以独特的魅力和强大的功能,在解决各类编程难题时发挥着至关重要的作用。今天,就让我们一同深入探索链表的奥秘。 目录 一、链表初相识 二、链表的结…...
微信小程序文件存储和获取的详细方案
在微信小程序中,要根据索引(如自定义标识符)检查是否存在对应的文件,可以通过以下方案实现。这里假设你已通过某种方式将文件路径与索引关联存储(例如使用本地缓存 Storage),以下是完整流程&…...
java BCC异或校验例子
需求 对一个十六进制的字符串进行BCC校验 方法 private static String XORCheck(String rawMsg) {// 16进制字符串需要转成10进制数组进行校验,然后再返回16进制字符串用于与原来的字符匹配byte[] bytes HexDumpMsgFormat.hexStr2DesBytes(rawMsg);return BytesUt…...
[machine learning] DP(Data Parallel) vs DDP(Distributed Data Parallel)
DP和DDP是并行训练的两种方法,本文简单介绍它们两者的区别。 一、DP (Data Parallel) DP是单进程,多线程的,每个线程负责一个GPU,它只适用于一台机器。DP训练的流程如下图所示(图片转载自:https://medium.com/mlshar…...
今日头条文章爬虫教程
今日头条文章爬虫教程 随着互联网的发展,新闻资讯类平台如今日头条积累了海量的数据。对于数据分析师、研究人员等群体来说,获取这些数据进行分析和研究具有重要的价值。本文将介绍如何使用Python编写爬虫,爬取今日头条的文章数据。 一、准…...
鸿蒙应用开发—数据持久化之SQLite
文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库,占用资源很少,只有几百KB的大小,无需服务器支撑,是一个零配置、事务性的SQL数据库引擎。 相对…...
Docker Compose 部署 steamcmd 安装奈斯服务端
由于打算在云端服务器部署奈斯启示录服务端跟朋友们一起玩, 所以在云端搭建服务器, 顺便写下本文章记录搭建的过程。 博主博客 https://blog.uso6.comhttps://blog.csdn.net/dxk539687357 要使用 Docker Compose 部署 steamcmd(Steam 命令行…...
K8s 1.27.1 实战系列(八)Service
一、Service介绍 1、Service 的作用与核心功能 Service 是 Kubernetes 中用于抽象一组 Pod 并提供稳定访问入口的资源。它解决了以下问题: Pod IP 不固定:Pod 可能因故障、扩缩容或更新导致 IP 变化,Service 通过 ClusterIP(虚拟 IP)提供固定访问地址。负载均衡:自动…...
Scala编程_实现Rational的基本操作
在Scala中实现一个简单的有理数(Rational)类,并对其进行加法、比较等基本操作. 有理数的定义 有理数是可以表示为两个整数的比值的数,通常形式为 n / d,其中 n 是分子,d 是分母。为了确保我们的有理数始终…...
Android15 Camera框架中的StatusTracker
StatusTracker介绍 StatusTracker是Android15 Camera框架中用来协调Camera3各组件之间状态转换的类。 StatusTracker线程名:std::string("C3Dev-") mId "-Status" Camera3 StatusTracker工作原理 StatusTracker实现批处理(状态…...
Manus 演示案例:谷歌公司运营模拟器游戏体验
一、项目背景与愿景 在科技行业蓬勃发展的当下,谷歌作为行业巨头,其成长历程充满了无数值得深入探究的决策智慧。这些决策不仅塑造了谷歌的辉煌,也为全球企业的发展提供了宝贵的借鉴。本项目旨在打造一款以谷歌公司发展为蓝本的运营模拟器游戏…...
【大模型基础_毛玉仁】2.1 大数据+大模型→新智能
【大模型基础_毛玉仁】2.1 大数据大模型→新智能 2.大语言模型架构2.1 大数据大模型→新智能2.1.1 大数据大模型→能力增强1)Kaplan-McCandlish 扩展法则2)Chinchilla 扩展法则 2.1.2 大数据大模型→能力扩展 2.大语言模型架构 大语言模型(L…...
20天 - TCP 和 UDP 有什么区别?说说 TCP 的三次握手?TCP 是用来解决什么问题?
TCP 和 UDP 有什么区别? TCP(传输控制协议)和 UDP(用户数据报协议)都是传输层的网络协议,它们的主要区别如下: 连接方式 TCP:面向连接的协议,类似于打电话,…...
【设计模式】掌握建造者模式:如何优雅地解决复杂对象创建难题?
概述 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。…...
【网络安全工程】任务11:路由器配置与静态路由配置
目录 一、概念 二、路由器配置 三、配置静态路由CSDN 原创主页:不羁https://blog.csdn.net/2303_76492156?typeblog 一、概念 1、路由器的作用:通过路由表进行数据的转发。 2、交换机的作用:通过学习和识别 MAC 地址,依据 M…...
10 【HarmonyOS NEXT】 仿uv-ui组件开发之Avatar头像组件开发教程(一)
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 目录 第一篇:Avatar 组件基础概念与设计1. 组件概述2. 接口设计2.1 形状类型定义2.2 尺寸类型定义2.3 组件属性接口 3. 设计原则4. 使用…...
蓝桥杯备赛-差分-重新排序
问题描述 给定一个数组 AA 和一些查询 Li,RiLi,Ri, 求数组中第 LiLi 至第 RiRi 个元素之和。 小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查 询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可 以增加多少? 输入格式 输…...
①Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网
Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网https://item.taobao.com/item.htm?ftt&id784749793551 MODBUS TCP 通信单元 MODBUS TCP 转 RS485 MS-A1-50X1 系列概述 MS-A1-50X1 系列概述 MS-A1-50X1系列作为MODBUS TCP通信的服务器进行动作。可通…...
2025年四川烟草工业计算机岗位备考详细内容
四川烟草工业计算机岗位备考详细内容(持续更新) 文章目录 四川烟草工业计算机岗位备考详细内容(持续更新)一、计算机基础(一)计算机发展与组成计算机发展历程计算机系统组成软件系统 (二&#x…...
Git 设置全局代理
Git 设置全局代理或项目代理 git config: 全局配置,设置git代理服务器 # 设置 HTTP 代理 git config --global http.proxy http://127.0.0.1:7897# 设置 HTTPS 代理 git config --global https.proxy http://127.0.0.1:7897# 设置所有协议的代理&…...
【Java开发指南 | 第三十四篇】IDEA没有Java Enterprise——解决方法
读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 1、新建Java项目2、单击项目名,并连续按两次shift键3、在搜索栏搜索"添加框架支持"4、勾选Web应用程序5、最终界面6、添加Tomcat 1、新建Java项目 2、单击项目名,并连续按两次…...
ROS实践(二)构建Gazebo机器人模型文件urdf
目录 一、基础语法 1. urdf文件组成 2. robot根标签 3. link 和 joint标签 4. sensor标签 二、 实验:使用launch文件启动rviz查看机器人模型 1. 编写机器人模型的urdf文件。 2. 编写launch文件。 3. 运行launch,查看效果。 URDF(Unifi…...
论文阅读-秦汉时期北方边疆组织的空间互动模式与直道的定位(中国)
论文英文题目:A spatial interaction model of Qin-Han Dynasty organisation on the northern frontier and the location of the Zhidao highway (China) 发表于:journal of archaeological science,影响因子:3.030 论文主要是…...
【MySQL_04】数据库基本操作(用户管理--配置文件--远程连接--数据库信息查看、创建、删除)
文章目录 一、MySQL 用户管理1.1 用户管理1.11 mysql.user表详解1.12 添加用户1.13 修改用户权限1.14 删除用户1.15 密码问题 二、MySQL 配置文件2.1 配置文件位置2.2 配置文件结构2.3 常用配置参数 三、MySQL远程连接四、数据库的查看、创建、删除4.1 查看数据库4.2 创建、删除…...
设计模式之建造者模式:原理、实现与应用
引言 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将复杂对象的构建过程分解为多个简单的步骤,使得对象的创建更加灵活和可维护。建造者模式特别适用于构建具有多个组成部分的复杂对象。本文将深入探讨建造者模式的原…...
2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB
一、山羊优化算法 山羊优化算法(Goat Optimization Algorithm, GOA)是2025年提出的一种新型生物启发式元启发式算法,灵感来源于山羊在恶劣和资源有限环境中的适应性行为。该算法旨在通过模拟山羊的觅食策略、移动模式和躲避寄生虫的能力&…...
Apache Log4j 2
目录 1. Apache Log4j 2 简介 1.1 什么是Log4j 2? 1.2 Log4j 2 的主要特性 2. Log4j 2 的核心组件 2.1 Logger 2.2 Appender 2.3 Layout 2.4 Filter 2.5 Configuration 3. Log4j 2 的配置 4. Log4j 2 的使用示例 4.1 Maven 依赖 4.2 示例代码 4.3 输出…...
ArcGIS Pro字段编号相关代码
一、引言 在地理信息系统(GIS)的数据管理与分析中,字段操作是不可或缺的一环。 SHP文件作为常见的地理数据存储格式,其字段的灵活运用对于数据的组织、展示和分析具有重要意义。 在实际工作中,常常需要对字段进行编…...
ubuntu22.04机器人开发环境配置
1. ros2环境配置(humble) #配置源 # https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update && sudo apt install curl -y# …...
万字深度剖析——JS数据结构(上)
数组本质是对象,键就是索引,值就是元素。 push /unshift 在数组最后/最前添加 pop /shift 把数组最后/最前的元素删除,返回的是被删除的元素 splice(0,2,5)从第0给位置开始删除2个元素,并添加一个元素 数组自带的…...
golang dlv调试工具
golang dlv调试工具 在goland2022.2版本 中调试go程序报错 WARNING: undefined behavior - version of Delve is too old for Go version 1.20.7 (maximum supported version 1.19) 即使你go install了新的dlv也无济于事 分析得出Goland实际使用的是 Goland安装目录下dlv 例…...
【算法 C/C++】二维前缀和
2025 - 03 - 08 - 第 70 篇 Author: 郑龙浩 / 仟濹 【二维前缀和】 文章目录 前缀和与差分 - 我的博客前缀和(二维)1 基本介绍(1) **sum[i][j] 表示什么???**(2) **前缀和怎么求???计算 sum[i][j]…...
如何使用postman来测试接口
一、postman的介绍与下载 可参考: https://blog.csdn.net/freeking101/article/details/80774271 二、api获取网站 阿里云API应用市场 地址:云市场_镜像市场_软件商店_建站软件_服务器软件_API接口_应用市场 - 阿里云 三、具体测试过程 可模拟浏览…...