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

Unity URP炫彩干涉效果:从薄膜干涉原理到Shader Graph实现

薄膜干涉是一种常见的光学现象,指光在透明薄膜上下表面反射后产生干涉,形成彩虹色条纹。其原理基于光程差导致的相长与相消干涉,不同波长的光被选择性增强或削弱。在计算机图形学中,这一物理现象被抽象为高效的数学模型,通过Shader编程实现动态色彩变化,为游戏和实时渲染带来独特的视觉表现力。技术实现上,常采用正弦函数结合噪声纹理来模拟色彩循环,利用法线与视角点积作为基础变量,加入噪声扰动模拟厚度不均,实现随视角变化的虹彩效果。在Unity URP渲染管线中,可通过Shader Graph可视化工具或手写HLSL代码

weixin_34026997的博客 294

[后端设计]innovus命令editPin详解?

先放命令,有空慢慢写。

m0_61003348的博客 5731

单片机数组前的code的作用

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

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

2023东华大学机试OJ进阶版1-81题

先排序。每次找两个最小的数,把其中一个置为两数之和,并累加这个和值,另一个数置为-1,然后再排序,重复操作,直到只剩下一个数。105。

m0_49263811的博客 2796

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

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

Cerman的博客 836

学习海康VisionMaster之圆查找

(1):ROI选中位置修正,并且修正信息需要选择刚刚创建的位置修正组件输出信息,这里的话后续的检测窗口一般都需要做这一步,因为大部分的应用场景都是需要用到实时跟踪的。圆查找模块是用于查找指定区域的圆,并且会输出该圆的相关参数信息,比如圆中心点,圆半径,圆是否存在等信息。7):剔除点数:和高级参数里面的剔除距离搭配使用的,就是过滤较远的边缘点,让拟合圆心出来的轮廓更加接近。中的圆查找,相当于就是拟合圆心,这个在视觉软件中的应用也是非常广泛的,通常用于定位,测量项目。

yuhouxiyang的专栏 2104

当启动容器的时候提示:exec format error?如何解决问题

Docker容器出现"exec format error"的主要原因是架构不兼容(如ARM设备运行x86镜像)。解决方案包括:1)匹配镜像与宿主机架构;2)构建时指定平台;3)安装QEMU模拟器;4)修复文件权限和格式;5)验证基础镜像兼容性。排查流程应从检查架构匹配开始,逐步验证权限、解释器和换行符等问题。建议优先使用多架构镜像,构建时明确指定平台,并使用buildx工具生成多平台镜像。调试时可进入容器手动验证文件格式和兼容性。

weixin_39291964的博客 2718

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

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

weixin_29185167的博客 264

Unity GameObject 核心机制深度解析:从底层结构到工程实践

从底层机制讲透 Unity GameObject:托管壳加原生芯的双层对象模型如何制造假 null 陷阱、Transform 层级与组件通信的原理、生命周期回调的确切顺序。文章同时给出 Instantiate 成本分析与对象池等高频场景的工程实践。

游戏人生 40

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

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

weixin_31139479的博客 155

Python库CloudScraper详细使用(绕过 Cloudflare 的反机器人页面的 Python 模块)

CloudScraper是一个专门用于绕过Cloudflare反机器人保护的Python库,它基于requests库构建,能够处理Cloudflare的5秒盾、WAF和人机验证等防护机制。

数据知道的博客 1万+

YOLO11涨点优化:注意力魔改 | 引入Deformable Attention (可变形注意力),灵活感受野自适应复杂形变目标

Deformable Attention为YOLO11带来的不仅是2.6个百分点的mAP提升,更是一种全新的“形变感知”范式。标准卷积的固定感受野在非刚性目标、多尺度变化和遮挡场景下力不从心——Deformable Attention恰好填补了这一空白。从架构设计到代码实现,从竞品对比到部署方案,从生态工具到安全风险,本文覆盖了将Deformable Attention引入YOLO11所需的全部知识链路。

2601_95807009的博客 284

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

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

weixin_42126677的博客 22

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

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

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

weixin_33363025的博客 109

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【硬核排障】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

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

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、付费专栏及课程。

余额充值