C/C++的预编译和宏定义

GCC/G++编译器和VS IDE中的一些预定义宏和用户自定义宏 预定义宏,  编译器通常会根据平台和编译选项的不同,为被编译的程序提供不同的预定义的宏, 例如WIN32 WIN64 LINUX, 例如DEBUG, RELEASE. 1. 在使用gcc/g++编译器时,可以通过以下命令打印出编译器预编译的宏。 gcc -dM -E - 2. 在VS IDE中,可以参看http://msdn.microsoft.com/zh-cn/libr 阅读详情

预编译是整个编译过程的第一步,是g++ -E选项输出的结果。

这个步骤处理的是源文件/头文件中的宏,宏指令常用的有以下几类:

  • 文件包含:#include
  • 宏定义:#define、#undef
  • 条件编译:#ifdef、#ifndef、#if、#elif、#else、#endif

1. 文件包含 #include

预处理会把要包含的文件的内容全部包含进来,比如下面这个文件prepro.cpp:

#include "prehead.h"
int main(){
  add(1, 2);
}

引入了头文件prehead.h:

#ifndef _PREHEAD_H
#define _PREHEAD_H
/* declaration of a function that add two integer */
int add(int, int);
#endif

使用命令g++ -E prepro.cpp预编译,输出结果如下:

# 1 "prepro.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "prepro.cpp"
# 1 "prehead.h" 1






int add(int, int);
# 2 "prepro.cpp" 2

int main(){
  add(1, 2);
}

可以看到结果中两个文件的宏定义都被删除了,文件prehead.h中注释也被删除了,而剩下的内容被引入了prepro.h中。至于#ifndef的意思最后介绍。

2. 宏定义:#define、#undef

#define宏定义的一种用法是声明一个宏,用来实现条件编译,这种用法后面和#ifdef等宏命令一起介绍。

#define宏定义的另一种用法是用来定义常量,定义准inline的函数。这种用法不好,应该避免使用。

使用#define定义的变量,比如:#define PI 3.14,预编译以后程序中所有的PI都会被3.14替代。再比如上次谈g++那篇博客的这个例子:

#define ONE 1
#define TWO 2

int add_one_two(){
  return ONE + TWO;
}

预编译后结果如下:

# 1 "add.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "add.cpp"

int add_one_two(){
  return 1 + 2;
}

可以看到定义的ONE被替换成了1,定义的TWO被替换成了2。

使用常量是好的,但是使用#define这种方法的不好是调试时候变量名都被替换了,失去了常量的效果。最好用下面这种方式定义变量:

const TYPE VAR_NAME=value

使用#define定义准inline函数,比如下面这个的例子(引自《effective C++》):

#define max(a, b) ( (a) > (b) ? (a) : (b) )

一般也没什么问题,但是:

int a = 5, b = 0;
max(++a, b);			/* a自增了两次 */
max(++a, b + 10);		/* b自增了一次*/

所以这样定义是会出问题的。使用#define定义函数的初衷是为了提高程序运行速度,但是这种方式提高速度有限,根本上应该从改进数据结构,算法方面入手。这种#define,果断写成inline就OK了,那么多括号写着累,看着也累,没必要。

3. 条件编译:#ifdef、#ifndef、#if、#elif、#else、#endif

条件编译算是宏最精髓的应用吧。先来说说这几个指令的意思,如果你看过我前面的博客,而且坚持在USACO上做题,那么想必你已经熟悉了C++最基本的语法,那这几个指令看一眼也能基本知道大概意思。下面用注释方式解释:

#ifdef				//if define,如果定义了。。。
#ifndef				//if not define,如果没有定义。。。
#if				// 如果。。。
#elif				// 或者如果。。。
#else				// 或者。。。
#endif				// 结束if

第一种条件编译

用来防止一个头文件引入两次。比如开始那个例子里面的头文件prehead.h:

#ifndef _PREHEAD_H		/* 如果没有定义_PREHEAD_H */
#define _PREHEAD_H		/* 定义_PREHEAD_H */
/* declaration of a function that add two integer */
int add(int, int);
#endif                         	/* 结束上面对应的#ifndef */

然后更改下我们的prepro.cpp文件,增加一行#include "prehead.h"

#include "prehead.h"
#include "prehead.h"
int main(){
  add(1, 2);
}

这里我手工展开,变成下面这个样子,然后在注释里面分析一下:

#ifndef _PREHEAD_H		/* 如果没有定义_PREHEAD_H */  /* 的确没有定义 */
#define _PREHEAD_H		/* 定义_PREHEAD_H */  /* 那么就定义之 */
/* declaration of a function that add two integer */
int add(int, int);
#endif                         	/* 结束上面对应的#ifndef */

#ifndef _PREHEAD_H		/* 如果没有定义_PREHEAD_H */  /* 上面已经定义了,条件为false */
#define _PREHEAD_H		/* 定义_PREHEAD_H */  /* 所以从这里开始到endif都会被预处理器删除 */
/* declaration of a function that add two integer */
int add(int, int);
#endif                         	/* 结束上面对应的#ifndef */  /* 后面的编译独立于第二个#ifndef _PREHEAD_H */

int main(){
  add(1, 2);
}

使用命令g++ -E prepro.cpp,输出和第一个例子里面一样,如下:

# 1 "prepro.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "prepro.cpp"
# 1 "prehead.h" 1



int add(int, int);
# 2 "prepro.cpp" 2

int main(){
  add(1, 2);
}

或许你会说,这个SB,一个头文件include两次,哈哈哈哈。但是,这只是个例子,实际项目中文件引入比较复杂,比如上面的prepro.cpp引入了第三个文件,然后第三个文件引入prehead.h,那么没有条件编译的话prepro.cpp里面就会有两个prehead.h。

使用#ifndef... #define... #endif可以保证一个文件只引入一次,这里的...可以是任何内容,只要你能保证定义的这个东西其他地方没定义,但是惯例是定义文件名的大写然后加几个下划线,像上面那个例子一样。

第二种条件编译

用来实现跨平台编译。比如下面这样:

#ifdef _linux_
// linux平台相关代码。。。
#endif
#ifdef _windows_
// windows平台相关代码。。。
#endif
#ifdef _macos_
// mac os平台相关代码
#endif

然后在某个include的配置文件config.h里面,如果有如下定义:#define _linux_,那么编译器就只编译linux平台相关的代码;如果有如下定义:#define _windows_,那么只编译windows平台相关的代码。

最后要说明的是,配置文件config.h不是手动写的,而是脚本自动生成的。至于如何编写脚本或者使用工具生成脚本,算是另一个话题了,以后再介绍吧。



宏指令还有其他一些,但是用的很少,我就不写了,想了解的朋友可以参考这个网址:点击进入。这个网站C++的文档,手册,帮助都一流,学习C++可以多看看。


参考文献:

Effective C++, third edition. Scott Meyers. 2005

使用gcc的-finstrument-functions选项进行函数跟踪 GCC Function instrumentation机制可以用来跟踪函数的调用关系,在gcc中对应的选项为“-finstrument-functions”。可查看gcc的man page来获取更详细信息。 编译时如果为gcc加上“-finstrument-functions”选项,那在每个函数的入口和出口处会各增加一个额外的hook函数的调用,增加的这两个函数分别为: void __cyg 阅读详情

相关推荐

Linux 下 C/C++ 程序编译的过程

本文将介绍如何将 C/C++ 语言编写的程序转换成为处理器能够执行的二进制代码的过程,包括四个步骤:预处理()编译()汇编()链接(在此之前,首先来看一下 GCC 工具链。

Projectsauron 的博客 3万+

宏(预编译)详解

_FILE__ //进行编译的源文件__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义我们不妨打印出来这些预定义符号int main()return 0;可以发现,打印出来的结果跟预期一样,由(__STDC__)的结果看,dev C++遵循ANSIC。

欢迎来到阿熊的blog~~ 2374

C/C++编译原理及过程整理

面试被问到C编译原理,所以回来整理一下。 编译主要分为四个大步骤:预编译、编译(.s、.asm)、汇编(.obj、.o、.a、.ko)、链接(.exe、.elf、.axf等),在C/C++中统称为编译。 (一)预编译 使用的gcc命令是:gcc –E 对应于预处理命令cpp a. 宏定义指令:将所有的#define删除,并且展开所有的宏定义。 b. 条件编译指令:处理所有的条件预编译指令,比如#i...

a063225的博客 1016

C++通过Makefile定义宏参数,传入程序

严格来说应该是通过C++编译工具g++ -D 参数传递宏参数,下面我们来一起操作起来。

weixin_45805339的博客 1056

SpringBoot3.X及SpringAi和jdk17以上版本集成MCP协议供大模型调用sse协议

MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 推出的开源协议,旨在实现大型语言模型(LLM)与外部数据源和工具的无缝集成,用来在大模型和数据源之间建立安全双向的链接。目标是成为 AI 领域的“HTTP 协议”,推动 LLM 应用的标准化和去中心化。本文主要讲解SpringBoot3.X版本和jdk17版本如何集成MCP协议 后续还有一个SpringBoot2.7和jdk1.8通过solon来实现@Service。

weixin_47247523的博客 788

RocketMQ 5.3.1 集成 Spring Boot 3.4.3 就这么简单

RocketMQ 是一个分布式消息中间件,支持发布/订阅模型,具有高吞吐量、高可用性和事务消息等特性。它广泛应用于日志处理、订单系统和异步任务等场景。Spring Boot 3.4.3 集成 RocketMQ 5.3.1 的过程异常简单,仅需少量配置即可实现消息的生产和消费。本文从环境搭建到代码实现,覆盖了核心步骤。

lssffy的博客 1385

c基础知识之预编译

#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; // c语言的执行流程 // 编译: 形成目标代码(.obj) // 连接:将目标代码与c函数库连接合并,形成最终的可执行文件。 // 执行 // 预编译(预处理),为编译做准备工作,完成代码文本的替换工作 // 头文件告诉编译器有这样一个函数,连接器负责找到这个函数的实...

mashaoshuai12的专栏 969

香橙派5上跑DeepSeek-R1的避坑指南:从模型下载到NPU加速全流程解析

本文详细解析了在香橙派5(RK3588)上部署DeepSeek-R1蒸馏模型的完整流程与优化技巧。内容涵盖从系统配置、RKLLM工具链编译、模型转换到NPU加速调优的全过程,重点分享了如何利用RK3588的NPU算力实现高效推理,并提供了常见问题的解决方案,为边缘设备部署LLM提供了实用指南。

CAT789的专栏 717

C/C++语言基础--预编译指令、宏定义(带参宏、宏函数)、头文件重复包含解决方法等

预定义宏是C语言中标准编译器预先定义的宏,在ANSI标准中C程序有5个预定义宏可以直接使用。宏说明LINE当前编译的代码的行号FILE当前编译文件的源文件名DATE当前源程序创建的日期TIME当前源程序创建的时间FUNCTION当前正在被访问的函数名int main()return 0;11:18:0410main注意:__FUNCTION__调bug特别好用,🤠#define 叫做宏定义命令,它也是C语言预处理命令的一种。所谓宏定义,就是用一个标识符来表示一个表达式。

羊小猪~~的博客 1728

离散系统傅里叶变换的常用结论证明

本文介绍了离散系统傅里叶变换的三个重要结论:1)时域卷积对应频域相乘(公式1-3);2)时域相乘对应频域卷积(公式4-6);3)帕塞瓦尔定理(公式7)及其广义形式,证明信号能量在变换域保持不变。文末提供了MATLAB卷积运算演示程序,通过动画展示离散信号卷积过程(翻转、平移、相乘、累加),并以方波信号为例给出运行结果图。该程序直观呈现了卷积运算的步骤与结果。

newtton的博客 1302

ardupilot SBUS输入捕获

本节主要记录ardupilot 的sbus 输入捕获功能。ardupilot 默认支持多种无线协议控制输入设备,比如常用的PPM,SBUS,IBUS,DSM,SUMD,SRXL等协议,本节主要讲解ardupilot 如何通过定时器的pwm输入捕获来获取sbus数据。

陌城烟雨 270

C/C++FAQ

Q:工程没有生成lib文件,只生成了dll文件 A:

917

SAP使用XCO框架创建RAP所有对象

通过XCO框架自动生成SAP ABAP开发对象。

DeveloperMrMeng的博客 548

C语言中的宏定义

C/C++语言中的宏定义 最近在阅读代码是发现一个宏定义很奇怪,变对C语言中的宏定义的基本知识进行了简单整理: 普通宏定义 函数宏定义 C语言中宏的调试方法 代码块 下列C代码中包含两种宏定义,例如: #include &lt;stdio.h&gt; #define MAX_CONNECTION 1000 #define MNG_PORT 5000 #define MI...

zhu4674548的专栏 4827

planning模块(6)-参考线的平滑(二次规划)

上一篇已经介绍了采样点生成锚点数据的过程,并且将所有采样点生成的锚点数据设置到了平滑器中.接下来继续介绍使用二次规划平滑参考线的算法过程.从锚点数据中提取坐标存入raw_point2d,提取横向边界存入anchorpoints_lateralbound,将起点和终点的横向边界设置为0,防止车在起点和终点位置偏离车道中心线.

让复杂的问题变得更容易理解 787

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

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

weixin_39291964的博客 2718

c、c++头文件中预编译的作用

c、c++头文件中预编译的作用在头文件中加入#ifndef或#ifdef等宏定义,是为了防止重复声明。 我们知道,头文件一般是用来声明的,会被其他的源文件和头文件include,当被多个文件include的时候就会造成重复声明。 为了使得只声明一次,引入前面所说的宏定义,一般以文件名大写和_来当宏的名字。 这个宏是给预处理器用的,通常预处理变量用大写,所以这些宏定义都用大写。为了方便,一般将大写的...

你轻轻地走了 690

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

预编译与编译

一C/C++源代码从最初的文本变为可执行文件主要进行三大步 预编译阶段:主要是编译器执行代码文本处理工作,并不会进行语法检查 主要执行三大类预编译命令 宏定义:代码文本替换功能,将使用了宏的地方采取宏定义方式直接展开 条件编译:代码文本剪切功能,根据设定的条件选择性删除一些代码片段 包含文件: 代码文本插入功能 #include 包含其他头文件,#include其内部实现是将被包含的头文件代码插入到当前代码文本中 编译阶段:将预编译阶段产生的带编译源码进行语法检查,编译成目标文件(.o类型.

一只老风铃 1889

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++学习——C/C++预处理指令和预编译选项

C/C++学习记录——预处理、预编译选项

qq_30101409的博客 567

深度学习工具包 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")

预编译应用(宏定义)用法及作用

存在,开始第一次编译。当第二次重复编译的时候,检查到。取消以前定义的宏定义;如果没有该定义,则忽略。三、#if #else #endif。这样当第一次编译的时候,检查到没有。四、#ifdef #endif。已经存在,不重复编译代码段。一、#define 宏。随便起得标识符XXX。随便起得标识符XXX。

WUAZ123的博客 251

C/C++预编译指令全解析:从入门到精通

C/C++预编译指令由#开头,在编译前由预处理器处理,主要用于宏定义、条件编译和文件包含。常用指令包括:#include(文件包含,区分<>和""路径)、#define/#undef(宏定义/取消)、条件编译指令(如#ifdef)、#pragma(编译器特定功能)等。关键应用场景包括头文件复用、跨平台适配、调试开关和结构体对齐控制。最佳实践强调宏定义加括号、优先用#pragma once防头文件重复包含,并注意宏命名规范。这些指令可有效控制代码编译过程,但需谨慎使用以避免移植

Shylock_Mister的博客 1381

C/C++条件预编译指令(宏定义)

自定义宏一定在.pro文件中添加宏定义或手动通过。

m0_56844552的博客 711

预编译时宏替换 见解

在预编译的过程中 主要处理# 和宏替换 例如 #include<stdio.h> #define PI 3.14 int main(){ double r=3, s; s=r*r*PI; printf("%f\n",s); return 0; } 在预编译的时候 代码变成如下 #include<stdio.h&...

weixin_30883777的博客 487

C语言的预编译

由“源代码”到“可执行文件”的过程包括四个步骤:预编译、编译、汇编、链接。所以,首先就应该清楚的首要问题就是:预编译只是对程序的文本起作用,换句话说就是,预编译阶段仅仅对源代码的单词进行变换,而不是对程序中的变量、函数等。 预编译指令的基本知识不作详细介绍,只稍作汇总,重点是后面的我能想到的 使用时的注意事项。1. 基本内容预编译指令基本分类如下类别指令预定义符号__FILE__...

weixin_30478619的博客 110

什么是预编译,何时需要预编译? 多个文件链接成一个文件

预编译又称为预处理 , 是做些代码文本的替换工作。 处理以# 开头的指令 , 比如拷贝#include 包含的文件代码,#define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段。   主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。   预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中

qq_36992917的博客 1073
上一篇: linux编程之查看帮助
下一篇: git命令
High_High
博客等级 码龄19年 131粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值