C硬核:聊聊预编译指令和宏的应用场景(一)

C/C++静态库封装实战:从原理到工程实践 在软件工程中,代码封装与模块化是构建可维护、可复用系统的核心原则。其基本原理在于通过接口与实现的分离,隐藏内部细节,对外提供稳定、清晰的契约。这一技术价值不仅体现在提升代码安全性和知识产权保护上,还能有效简化项目结构、加速编译过程,并强制良好的架构设计。在实际应用场景中,当需要将核心算法、业务逻辑或基础组件以二进制形式分发给客户、合作伙伴或跨项目集成时,静态库(Static Library)便成为一种经典且高效的解决方案。它通过将源代码预编译为目标文件并打包,使核心实现安全地“溶解”在最终的可执行文件中,避 阅读详情

C语言硬件编程栏目

往期文章:工作数年还是被指针坑了——谈谈C语言指针运算



前言

C语言编程中离不开预编译指令,编译器在预编译阶段,会根据预编译指令对你编写的代码进行处理。
例如,我们在写第一段C程序"HelloWorld"的时候,就用到了#include指令来包含stdio.h这样的头文件了;
而用于定义宏名称的指令#define也属于预编译指令,而且也是用的最多的预编译指令。
下面我们就围绕预编译指令和宏的应用场景,看看哪些是容易被忽略的预编译指令以及重要的应用场景。


一、预编译指令

C中的预编译指令很多,包括#define,#undef,#if,#ifdef,#ifndef,#error,#line, #pragma等等,常用且重要的指令主要是如下这些:

#define指令

编程中最常用的预编译指令要属#define宏定义指令了,其用法及形式如下:

#define NAME stuff

这样在code中其他使用NAME宏名的地方,都会被替换为stuff,这里的stuff可以是各种文本;最常见的常量数值,例如

#define PI 3.1415926

如果要移除一个前面定义的宏,用#undef即可。

#if指令

#if指令用于编译过程的分支判断,和#elif/#else/#endif配合使用。其形式如下:

#if Constant-Expression
  statements
#elif Constant-Expression2
  statements2
#else
  statements3
#endif

因为在Constant-Expression域内可以填写各种表达式的组合,所以该指令往往使用起来灵活多变。例如和defined/!defined配合使用,从而限定某个条件下编译的code,该用法也是常常不被重视但颇有用的一种:

#if defined(MACRO_A) && !defined(MACRO_B)
  statements
#endif

这样只有在定义MACRO_A和未定义MACRO_B的时候,才会执行如下的statements。

#ifdef指令

#ifdef指令和#if defined指令是等价的,所以常用#ifdef和#ifndef来实现宏定义下或非定义宏的条件下对code的执行,使用起来简单,但是没次只能对一个宏进行判断,不如#if指令灵活。

#include指令

该指令用于包含code中所需要的头文件,需要注意的是,包含的形式有两种:

//first one
#include <Library/file.h>
//second one
#include "file.h"

两者在检索头文件的过程中,是完全不一样的。第一种会按照编译器指定的库文件目录为根,向下检索头文件;而第二种则会按照当前编辑的C文件为根,去检索file.h。因此我们在使用的时候,如果头文件位于当前目录下,使用第2种方式最佳。

#pragma指令

一定注意,该指令名称是#pragma,不是#progma!
该指令稍显复杂,用于设定编译器的状态,指示编译器完成特定的动作。经常配合使用的参数包括message,warning和pack。而我们最常用和最重要的,就是和pack的搭配使用了。使用形式如下:

#pragma pack(n)

在默认情况下,对于结构体是按照最节省空间的方式进行对齐的,如下面的TestStruct1按照最大长度的int i进行对齐,c1/s/c2整体拼成一个单元,如表中所示,即按照pack(1)一个字节进行对齐:

struct TestStruct1
{
   char c1;
   short s;
   char c2;
   int i;
};

内存分布表
内存分布表

当然,上述默认的方式不一定适合编程时数据的访问,如果统一按照4个字节int类型进行访问,那么在结构体声明时使用pack(4)即可,那么这里的内存分布会变成:

c1
s
c2
i

取消自行设定的对齐方式,再使用#pragma pack()即可。下次我们以UEFI kernel为模板,再聊聊宏的应用场景~

宝塔面板下Nginx集成GeoIP2模块实战指南 本文详细介绍了在宝塔面板环境下,为Nginx手动编译并集成GeoIP2模块的完整实战指南。通过步骤解析,帮助用户实现基于IP地址识别访客地理位置的功能,从而轻松实现网站内容地域限制、差异化展示或流量屏蔽,提升运维效率与安全性。 阅读详情

相关推荐

Python项目内网迁移实战:依赖打包与离线部署指南

本文详细介绍了Python项目在内网环境中的完整迁移与部署流程。针对无法连接外网的情况,提供了从外网精准生成依赖清单、下载离线依赖包,到内网创建虚拟环境、离线安装依赖的实战指南。文章还探讨了搭建私有PyPI仓库等进阶方案,并分享了关键的避坑经验,帮助开发者高效、可靠地完成项目内网部署。

ee345的博客 358

c 宏的常用场景应用举例

c 宏的常用场景应用举例

xie__jin__cheng的博客 837

1 宏的使用大全

宏,也叫宏定义,并不是C/C++语言本身的一部分,不能直接对宏进行编译。在编译程序前,必须先对宏进行预先的处理(专业术语叫作“预处理”)。预处理器会分析所有的源文件,当遇到宏名称严格匹配时,就会展开宏,也就是用定义好的文本来代替宏名称。宏的用途主要有三点:一是可以为程序员的开发提供一定的便利性;二是可以有效减少源文件中大量重复的、相似的代码;三是可以在一定程度上减少系统的开销,提高程序的运行效率。C/C++语言预定义了一些宏定义,常用的宏定义如下表。宏名称数据类型备注__FILE__字符串。

hope_wisdom的技术博客 3570

宏的常见应用领域

1,跨平台,通过宏可以编译相应操作系统的api 2,定制业务,同一份代码,面向不同的客户,通过宏来定制。 3,Release 和 Debug。在release下,不能崩的,在debug下,是希望尽早暴露问题的。

wusoule的专栏 1257

别再傻傻分不清!5分钟搞懂倾斜摄影里‘地面分辨率’和‘模型精度’到底啥关系

本文深入解析倾斜摄影中‘地面分辨率’与‘模型精度’的关系,帮助读者快速理解两者的本质区别与内在关联。通过实战案例和公式计算,详细说明如何从航飞设计到精度验证全流程控制,避免常见认知误区,并针对不同应用场景提供精度需求建议。

weixin_33700350的博客 477

(一)ANSYS WORKBENCH实践入门

ANSYS-workbench 有限元分析应用基础教程 (张晔)学习笔记

qq_51767372的博客 1万+

单片机数组前的code的作用

目录code的作用 RAMROMRAM和ROM相比节约RAM空间的作用没用code 时,数组定义在RAM里面,有code时,数组定义在ROM里面(固定的数据,不能修改) RAM又被称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。当电源关闭时RAM不能保留数据(掉电数据消失哦)如果需要保存数据,就必须把它们写入一个长期的存储设备中(例如硬盘)。 ROM又被称为“只读存储器”,ROM所存数据,一般

公众号:风景邮递Yuan的博客 1827

工业级24V电源保护电路深度解析:五重防护机制详解

自恢复保险丝(PPTC,Positive Temperature Coefficient)是一种过流保护元件✅可恢复:过流后自动恢复,无需更换⚡响应快:电流超标立即动作🔄多次使用:在额定范围内可反复使用第1层(F1):阻挡过流 → 物理熔断第2层(D3):吸收浪涌 → 能量泄放第3层(Q1):防止反接 → 逻辑阻断第4层(Q2/Q3):抵御过压 → 主动切断第5层(CR):平滑启动 → 时序控制设计哲学:"让每一级保护专注做好一件事"通过这篇文章,我们深入理解了:✅自恢复保险丝。

qq_58068673的博客 3570

C硬核:聊聊预编译指令和宏的应用场景(二)

C语言硬件编程栏目 往期文章: 工作数年还是被指针坑了——谈谈C语言指针运算 C硬核:聊聊预编译指令和宏的应用场景(一) C硬核:聊聊预编译指令和宏的应用场景(二)C语言硬件编程栏目前言一、如何方便维护那些值不变的参数?二、如何对你的printf/debug语句分级?1.定义DebugPrintErrorLevel的划分细则2.设计和Error Level相关联的print函数3. 调整宏DebugPrintErrorLevel或入口参数errorlevel三、如何批量替换一系列代码?总结 前言 关

Cerman的博客 836

飞塔防火墙认证绕过漏洞(CVE-2022-40684)深度剖析与实战复现

本文深度剖析了Fortinet飞塔防火墙高危认证绕过漏洞CVE-2022-40684的原理与影响。该漏洞允许攻击者通过构造包含特定Forwarded头和User-Agent的HTTP请求,无需凭证即可绕过认证,以管理员身份访问设备。文章详细演示了从环境搭建到实战复现,最终植入SSH密钥获取控制权的完整过程,并提供了漏洞挖掘技巧与关键防御建议。

d6e7f8g9h的博客 708

系规备考论文:论IT服务规划设计

系规备考论文:论IT服务规划设计

liuxu324的博客 1144

ESP32C3启动流程揭秘:从复位向量到RTOS调度的关键步骤

本文深入解析了ESP32C3芯片从复位向量到RTOS调度的完整启动流程。详细拆解了ROM一级引导程序、Flash二级引导程序的关键步骤,包括启动模式选择、复位原因处理、分区表解析、安全启动验证等核心环节,并阐述了FreeRTOS调度器如何最终接管系统,为开发者解决启动相关问题和优化系统性能提供清晰指引。

weixin_29185167的博客 264

Linux ARM平台开发系列讲解(GPIO子系统) 2.3.2 GPIO子系统常用函数解析

1. 概述 该章节会记录一年常用的GPIO子系统常用函数,会更具情况不断更新 static inline int gpio_get_value(unsigned int gpio) 功能 :用于获取某个GPIO引脚上的值 gpio : gpio引脚号 返回值:非负值,得到的 GPIO 值;负值,获取失败。 static inline void gpio_set_value(unsigned int gpio, int value) static inline int gpio_cansleep(unsi

DSMGUOGUO的博客 668

SenseVoice-Small语音识别入门:C语言调用ONNX Runtime推理引擎教程

本文介绍了如何在星图GPU平台上自动化部署sensevoice-small-语音识别-onnx模型(带量化后),实现高效的本地语音识别应用。通过C语言调用ONNX Runtime推理引擎,开发者可以轻松集成该模型,适用于嵌入式设备或桌面程序的语音转文字场景,如语音指令识别、实时字幕生成等。

weixin_31139479的博客 155

无限泛化!AI背景文字识别,腾讯文字六宫格

本文介绍了生成大规模文字验证码数据集的方法,通过使用上百种字体和2万+字库,结合随机背景和数十种图像增强技术,生成了2000万+的多样化样本。该方法采用二阶段训练策略,确保模型对字体、形态、形变等具有强泛化能力,可适配腾讯、咸鱼等多种平台的文字验证码识别,包括生僻字和复杂形变情况。生成的模型在多种验证码场景下表现优异,但强调该方法仅用于技术研究,严禁非法用途。

码王吴彦祖的博客 563

【OpenCV-Python】——图像处理基础&读写及显示图像&读写及播放视频&灰度图/彩色图/图像通道操作、运算

在Python中,OpenCV使用NumPy数组存储图像,Numpy是使用Python进行数组计算的软件包,提供强大的N维数组对象,支持复杂的广播功能(数组运算),集成了C/C++和Fortran代码工具,支持线性代数、傅里叶变换和随机数等特性,还可作为通用数据的高效多维容器,如在OpenCV中显示图像。Numpy的知识点见数据处理专栏,主要包括数据类型、创建数组、数组形状、索引切片和迭代、数组运算等。作为初学者,里面可能有总结不全,后续深入学习后会改善文章!下次学习图形用户界面!

weixin_51658186的博客 2084

云容笔谈·东方红颜影像生成系统C语言基础调用示例:通过C接口实现高性能集成

本文介绍了如何在星图GPU平台上自动化部署💃 云容笔谈 · 东方红颜影像生成系统镜像,并通过C语言接口实现高性能集成。该方案特别适用于对性能有极致要求的场景,例如在嵌入式设备或服务器中直接调用模型进行AI图片生成,从而满足低延迟、高效率的内容创作需求。

weixin_42126677的博客 22

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

李慕婉-仙逆-造相Z-Turbo C语言基础调用示例:轻量级嵌入式集成探索

本文介绍了如何在星图GPU平台上自动化部署李慕婉-仙逆-造相Z-Turbo镜像,并探索了其轻量级C语言调用方案。该方案使资源受限的嵌入式设备能通过网络API调用该AI模型,实现水墨画风格等特定场景的图片生成功能,为边缘AI应用提供了高效集成路径。

weixin_33363025的博客 109

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【硬核排障】Windows 下 Python 报 DLL load failed?从 CPython 编译机制讲透 VC++ 依赖地狱(附 AIO 修复包)

本文深入分析了Windows下Python报DLL加载失败的底层原因,主要涉及CPython解释器与MSVC运行库的依赖关系。文章指出: CPython核心和许多Python扩展库实质是通过C-API封装的DLL文件,依赖MSVCRT运行库 手动下载DLL文件存在架构兼容性和程序集注册问题 提供了DLL依赖链诊断脚本定位缺失文件 推荐使用微软官方VC++ AIO运行库合集进行修复 提供了包含静默安装脚本的完整修复包下载地址 解决方案避免了安装臃肿的Visual Studio,通过官方运行库即可解决DLL加载

ai-codex-python博客 213

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ARM Cortex-M1 FPGA软核:技术遗产、商业博弈与当代启示

在嵌入式系统与可编程逻辑领域,处理器软核扮演着连接硬件灵活性与成熟软件生态的关键角色。其核心原理在于通过硬件描述语言在FPGA内部构建可定制的计算单元,实现软硬件协同设计。这项技术的价值在于能针对特定应用优化性能与功耗,并复用庞大的现有软件资产。典型的应用场景包括实时控制、信号处理加速和高度定制化的嵌入式系统。ARM Cortex-M1作为一款专为FPGA优化的32位ARM处理器软核,正是这一技术路线的早期重要实践。它基于Cortex-M3架构深度裁剪,支持Thumb-2指令集与紧耦合内存(TCM),旨在将

weixin_30565327的博客 465

为什么从 esptool.py 转向 espflash:Rust 版 ESP32 串口烧录工具的 3 个硬核优势

做嵌入式开发的朋友,大概率都用过 esptool.py 给 ESP32 刷固件。但 Python 环境依赖、烧录后还得自己开串口监视器、无法融入 Rust 工作流——这些痛点,**espflash** 一次全解决了。 espflash 是一款基于 Rust 实现的 **ESP32 串口烧录工具**(Serial flasher utility),功能对标 esptool.py,支持 **ESP3

gitblog_00483的博客 649

嵌入式开发自学指南:从C语言到RTOS与Rust的实战路径

嵌入式开发是计算机系统与物理世界交互的核心技术领域,其本质在于通过微控制器或微处理器执行特定任务,实现对硬件设备的直接控制。其技术原理建立在底层硬件认知、高效的编程语言以及实时操作系统之上,通过直接操作寄存器、管理内存和处理中断来确保系统的可靠性与实时性。这一技术价值在于能够构建高可靠性、低功耗且响应迅速的系统,广泛应用于物联网、汽车电子、工业控制及消费电子等场景。对于初学者而言,掌握以C语言为核心的编程基础、理解ARM Cortex-M系列微控制器架构,并熟练使用如VSCode配合GCC和OpenOCD的

weixin_30482383的博客 529

Python离线开发全攻略:从Whl到Anaconda虚拟环境

本文详细介绍了Python离线开发的两大核心方法:手动处理Whl文件与迁移Anaconda虚拟环境。针对无法联网的开发场景,文章提供了从依赖包递归下载、安装顺序到完整环境打包迁移的实战指南,并分享了搭建本地仓库、依赖清单管理等高级技巧,帮助开发者在封闭环境中高效部署Python项目。

weixin_29063035的博客 221

在 Deepin 20.9 + N卡 930MX(2GB) 上跑 Qwen3.5 模型

折腾日志。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 862

你心中最硬核的中国芯是谁?

慕尼黑华南电子展将推出特色活动专区及活动包括:智慧出行科技园、物联网科技园、硬核中国芯科技园、特斯拉model3拆解秀,以及意在扶植华南初创企业的创新公园。通过更深入的交流学习及系统集成...

634

ESP-IDF静态库实战:从组件原理到链接错误排查

在嵌入式开发中,静态库(.a文件)是代码复用和模块化协作的核心载体,尤其在ESP-IDF框架下,每个组件最终都会被编译成静态库再统一链接。理解这一构建机制,是高效排查undefined reference等链接问题的关键。ESP-IDF通过组件目录和CMakeLists组织源码,编译后生成独立的目标文件并打包,链接时按需提取符号。静态库不仅有助于保护知识产劝、加速增量编译,还能通过-ffunction-sections和--gc-sections等选项有效控制固件体积。在实际的ESP32、ESP32-S3、

weixin_27869497的博客 233
上一篇: 浅谈电力电子中的双脉冲测试
下一篇: C硬核:聊聊预编译指令和宏的应用场景(二)
Cerman
博客等级 码龄11年 63粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cerman

你的鼓励是探索和创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值