预处理指令

预处理指令,第1张

以上内容总结至:微软官网https://docs.microsoft.com/zh-cn/cpp/preprocessor/preprocessor-directives?view=msvc-170

预处理器指令:(如 #define 和 #ifdef )通常用于使源程序在不同的执行环境中易于更改和编译预处理器语句使用的字符集与源文件语句相同,但转义序列不受支持。 预处理器语句中使用的字符集与执行字符集相同。 预处理器还可识别负字符值。

常见的预处理关键词:

  •  (#) 必须是包含指令的行上的第一个非空白字符
  • 指令后面的任何文本都必须以单行注释分隔符开头 (//) 或括在注释分隔符 (/* */)
  • 预处理器指令的行可以通过紧靠在行尾标记前面,使用反斜杠 (\
#define :

创建一个宏,该是标识符或参数化标识符与标记字符串的关联。 在定义宏之后,编译器可用标记字符串替换源文件中标识符的每个匹配项

#define  I   30  //把 I 定义为整形常量

//这两种的区别
#define  P (x+y)
#define  P(x,y)  x+y

int x=20;int y=30
求 k=x*P(x,y)*y
//第一种
k=x*(x+y)*y=20*(20+30)*30=30000
//第二种
k=x*x+y*y=20*20+30*30=1300
#undef :

移除(取消定义)之前使用 #define 创建的名称

#define  P (x+y) //创建
#define  P1  x+y //创建
...
...
#undef P  //删除
#undef P1 //删除
 #error:

在编译时发出用户指定的错误消息,然后终止编译

#if、#elif、#else 和 #endif  :

控制源文件部分编译:

#if 每个命令指令都必须由结束的 #endif 指令匹配 。 在 #elif 和 #if 指令之间#endif任意数目的 #else 指令,但最多允许一#else指令。 如果存在 #else ,则此指令必须是最后一个指令,然后才能 #endif。#if、#elif、#else 和 #endif 指令可以嵌套在其他 #if 指令的文本部分中。 每个 嵌套#else、 #elif 或 #endif 指令都属于 最近的前一 个#if指令。

格式:

#if ......

#elif......//可以没有这一行

#else.....

#endif.... 

defined:预处理运算符 

用法:

已 (标识符)
定义标识符

#if defined(CREDIT)
    credit();
#elif defined(DEBIT)
    debit();
#else
    printerror();
#endif
//如果定义了 CREDIT ,则编译对credit()调用
//如果定义了标识符 DEBIT,则编译对 debit 的函数调用。 
//如果两个标识符都未定义,则编译对 printerror 的调用。
假设 p是一个已定义的量
#if    p>5
     #define G  1
#elif  p=5
     #define G  2
#else 
     #define G  3
#endif
//当p大于5时  G 为 1
//当p等于5时  G 为 2
//两个都不满足时  G 为 1
#ifdef 和#ifndef 

相当于:#if  defined ...     #if !defined ...

提供这些指令只是为了实现与该语言的早期版本的兼容性

首选 defined(identifier) 与 指令一起使用的 #if 常量表达式。

#import  :(C++专用)

过去一直合并类型库中的信息。 类型库的内容将转换为 C++ 类,主要描述 COM 接口

#import "filename" [attributes]
<#import文件名>[属性]

#include :头文件

告知预处理器在 指令出现时包含指定文件的内容。

#include "path-spec" //用户自定义的文件
#include <path-spec>//系统文件
#include//系统文件
#include"Person.h"//用户自定义文件
C++ 中的预定义宏

C++ 提供了下表所示的一些预定义宏:

描述
LINE这会在程序编译时包含当前行号。
FILE这会在程序编译时包含当前文件名。
DATE这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。
TIME这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。
#include 
using namespace std;

int main ()
{
    cout << " __LINE__ : " << __LINE__ << endl;
    cout << "__FILE__ : " << __FILE__ << endl;
    cout << " __DATE__ : " << __DATE__ << endl;
    cout << " __TIME__ : " << __TIME__ << endl;

    return 0;
}
结果为:
__LINE__ : 6   //行号
__FILE__ : test.cpp //文件
__DATE__ : Feb 28 2011 //日期
__TIME__ : 18:52:48 //时间
预处理器运算符:
*** 作员 *** 作
字符串化运算符 (#)使相应的实际参数用双引号引起来
字符化运算符 (#@)使相应的参数括在单引号中,并被视为特定于 Microsoft (字符)
标记粘贴运算符 (##)允许连接用作实际参数的令牌以形成其他标记
defined 运算符简化了在某些宏指令中编写复合表达式
运算符用于连接两个令牌:

#define CONCAT( x, y )  x ## y

#include 
using namespace std;
 
#define concat(a, b) a ## b
int main()
{
   int xy = 100;
 
   cout << concat(x, y);  //结果为100  concat 把(x,y)拼接成 xy
   return 0;
}

 

宏和 C++ :
  • 在 C++ 中,声明为 const 的对象可用于常量表达式。 它允许程序声明具有类型和值信息的常量。 它们可以声明可以使用调试器以符号方式查看的枚举。
  • 使用预处理器指令 #define 定义常量时,它并不精确,也不为类型安全。 不会为 对象分配任何存储 const ,除非程序包含采用其地址的表达式。
  • C++ 内联函数功能取代了函数类型宏。 使用内联函数取代宏的好处如下:

    • 类型安全。 内联函数需要接受与常规函数相同的类型检查。 宏不是类型安全的

    • 纠正具有副作用的参数的处理。 内联函数在输入函数体之前计算作为参数提供的表达式。 因此,具有副作用的表达式不会不安全。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1324330.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-12
下一篇2022-06-12

发表评论

登录后才能评论

评论列表(0条)

    保存