预编译宏

不带参数的宏  -----------------------------------------------------

形式:

#define  宏名称   替换主体

注意:

  • 替换主体中可以有空格空格不是替换主体的一部分(这也很好理解,因为编程的时候执行语句也一般是忽视中间的空格的就好比 a = 3; 与 a=3;是等价的一样 ),例如  #define SIX      2         *3 (等价于 #define SIX 2*3)
  • 但是替换主体的内容还是要遵照一定的规定表达式的数据和操作符中间可以有空格但是一个数据中不能存在 (比如不能这样定义宏 #define PI    3     .14  或者  #define PI    2       2) 

例子:

复制代码
 1 #define PI 3.14      //下文出现 PI 的时候都用 3.14 去替换
 2 #define SIX 3+3     //下文出现 SIX 的时候都用 3+3 去替换
 3  
 4 void mian()
 5 {
 6       int x;
 7       x = PI;    //等价于 x = 3.14
 8       x = SIX * 5    //这里注意了,x的值为 18 而不是 30
 9             //因为宏只做简单替换也就是这里等价于 x = 3+3*5 所以x值当然是18了
10 }
复制代码

 

带参数的宏  --------------------------------------------------------

形式:

#define   宏名称(参数列表)    替换主体

定义:

类函数宏的定义中,用圆括号括起来一个或多个参数,随后这些参数出现在替换部分

例子:

1 #define  MAX(x,y)  (x>y? x: y)

#运算符  ----------------------------------------------------------

形式:

#define   宏名称(参数列表)   替换主体

定义:

#符号把语言符号字符串化(也就是 用 "宏参数" 去替换替换主体中的 #宏参数  )

例子:

1 //定义宏
2 #define  PSQR(x) cout<<"it is " #x<<endl;
3 
4 //然后调用PSQR
5 PSQR(x)   //输出的结果为: it is x

 

##运算符  --------------------------------------------------------

形式:

#define  宏名称(参数列表)   替换主体

作用:

  • ##后面紧紧跟着的是宏参数
  • 这个语言符号组合成单个语言符号,也就是把替换主体与宏参数结合成一个语言符号
  • 宏参数在编译阶段只简单看成字符或字符串没有其他含义

例子:

复制代码
 1 // 例1 ----
 2 //定义宏
 3 #define  XNAME(n)  a##n  
 4 
 5 //调用宏
 6 char a1 = 'x';
 7 cout<<XNAME(1)<<endl;     //输出结果为: x
 8  
 9  
10  
11 // 例2 ----
12 //定义宏
13 #define  XNAME(n)  a##n = '6'  
14  
15 //调用宏
16 char a1 = 'x';
17 XNAME(1); 
复制代码

 

取消宏定义#undef  -------------------------------------------------

形式:

#undef   宏名称

作用:

取消定义过的宏

例子:

1 #define TWO 2
2 #undef  TWO    //  取消宏定义在以后的地方TWO这个宏就不存在了

 

预定义宏  -----------------------------------------------------------

  • 本机日期              __DATE__
  • ‘1’为遵循c标准            __STDC__
  • 文件名                 __FILE__
  • 为本机环境设置1,否则为0     __STDC_HODTED__
  • 行号                __LINE__
  • 为c99时设置为1999901L      __STDC
  • 本机时间             __TIME__

 

杂项  ---------------------------------------------------------------

作用域:

作用域是文件,或者直到遇到undef为止

注意事项:

  • 宏的名字不能有空格,并用圆括号括住每个参数,例如#define f  (x)  ((x)+1)尽管你想表达的是f(x)用((x)+1)的意思但是结果编译器却认为是f用(x)((x)+1)代替
  • 宏不是函数,宏在编译时期只是做简单的替换
  • 宏不是类型定义,因为它只作简单替换,对于类型定义最好用typedef来完成,比如#define F int*,与typedef int* F时用F去声明变量时, F a,b.宏只能做到把第一个变量声明成指针,而后一却是声明变量.而typedef可以把两个都声明成指针(关于typedef)

  • 如果使用宏,加快程序运行速度,首先确定是否会引起重大差异

优缺点:

预处理器不对宏进行计算,而只是简单进行字符串替换,宏不检查其中变量类型,但宏会产生内联代码,而且比内联函数花费的时间多,比函数占的内存更大

 

[返回目录]


 

 

其他的预编译

 

#line  --------------------------------------------------------------

作用

  • #line命令是用于更改__LINE__ 和 __FILE__变量的值. 文件名是可选的. __LINE__ 和 __FILE__ 变量
  • 描述被读取的当前文件和行. 命令 <例:#line 10,“cool,cpp”//把行号重置为10,文件名为“cool.cpp”>

 

#error  ------------------------------------------------------------

作用

使预处理器发出一条错误消息,该消息包含指令文本

 

条件编译  -----------------------------------------------------------

说明:

#ifdef ,#else , #elif ,  #ifndef , #if  和 #endif (用法与if…else相似)

作用:

可以防止头文件被重复定义

例子:

防止头文件被多次定义的例子:

复制代码
 1 //防止头文件被多次定义
 2 //以 iostream 头文件为例子
 3 // 方法1 ----
 4 #ifndef __IOSTREAM_H__
 5 #define __IOSTREAM_H__   1
 6 #include <iostream>
 7 #endif 
 8   
 9   
10 // 方法2 ----
11 #pragma once
12 #include <iostream>
13  
14   
15 // 方法3 ----
16 #if !defined(__IOSTREAM_H__)
17     #define __IOSTREAM_H__   1
18     #include <iostream>
19 #endif
20 //一般不提倡这么用就是了
复制代码

再来看一个来自于微软技术资源库的例子:

复制代码
 1 // 例1 --
 2 #if defined(CREDIT)   //defined(CREDIT)  代表的是是否定义过CREDIT这个宏
 3                       //如果定义过返回真,没定义返回假
 4     credit();
 5 #elif defined(DEBIT)
 6     debit();
 7 #else
 8     printerror();
 9 #endif
10 
11 
12 //例子2 --
13 #if DLEVEL > 5              //#if   后面也可以接条件表达式
14     #define SIGNAL  1
15     #if STACKUSE == 1
16         #define STACK   200
17     #else
18         #define STACK   100
19     #endif
20 #else
21     #define SIGNAL  0
22     #if STACKUSE == 1
23         #define STACK   100
24     #else
25         #define STACK   50
26     #endif
27 #endif
28 #if DLEVEL == 0
29     #define STACK 0
30 #elif DLEVEL == 1
31     #define STACK 100
32 #elif DLEVEL > 5
33     display( debugptr );
34 #else
35     #define STACK 200
36 #endif
复制代码

这里就简单的让你了解下条件编译的运用,例子的链接为:http://technet.microsoft.com/zh-cn/library/ew2hz0yd(v=vs.110)

 

杂项  ---------------------------------------------------------------

“预编译命令”的两大步骤:

  • 先进行一次“预编译对所有预编译命令进行处理,把#include包含的头文件内容调出来放到#include命令的位置
  • 进行正式编译工作,得到目标文件(后缀为obj)(不要把符号常量与变量混淆,符号常量只是一个符号,不占存储单元,习惯上,符号常量名用大写,变量名用小写,以好区分,使用符号常量好处①含义清楚;②在需要时可改)

 [返回目录]


在VSCode中,预编译是一种在编译过程中定义的。根据语言(C或C++)、编译目标和选定的编辑器选项,Visual C编译器会预定义某些预处理器预编译一般以"__"开头和结尾,中间的单词使用大写字母,并使用下划线连接单词。例如,__FILE__是一个预定义,用于表示当前文件的文件名。 在VSCode中,可以在task.json文件中针对gcc添加编译命令来定义预编译。具体的操作包括在args选项中添加"-D"参数,后面跟上需要定义的名称。例如,"-DENACMP"表示在编译时定义了ENACMP。 总结起来,如果想在VSCode中使#ifndef后的代码块变暗,并在实际运行代码时确保预编译定义,需要在task.json文件中的args选项中添加"-D"参数来定义。这样在编译过程中,预编译将起作用,并且在鼠标移到上时会显示的定义。但需要注意,VSCode中的配置和设置相对于VS来说需要更多的自己摸索和设置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vscode添加预编译定义](https://blog.csdn.net/BaLa_Boom/article/details/131792585)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [c++预编译(持续更新)](https://blog.csdn.net/u014128662/article/details/89006523)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值