预处理指令讲解

预处理指令是我们写在程序代码中的给预处理器(预处理器)的命令,而不是程序本身的语句。预处理器在我们编译一个C ++程序时由编译器自动执行,它负责控制对程序代码的第一次验证和消化。

所有这些指令必须写在单独的一行中,它们不需要加结尾的分号。

#deine

在这个教程的开头我们已经提到了一种预处理指令:#define,可以被用来生成宏定义常量(定义常数或宏),它的形式是:#define name value

#define也可以被用来定义宏函数:

#define getmax(a,b)a> b?a:b
int x = 5,y;
y = getmax(x,2);

这段代码执行后y的值为5。

和#undef

#undef完成与#define相反的工作,它取消对传入的参数的宏定义:

#ifdef,#ifnf,#if,#endif,#else和#elif这些指令可以使程序的一部分在某种条件下被忽略

#ifdef可以使一段程序只有在某个指定常量已经被定义了的情况下才被编译,无论被定义的值是什么。它的操作是:

#ifdef name
// code here
#endif

例如:

#ifdef MAX_WIDTH
char str [MAX_WIDTH];
#万一

在这个例子中,语句char str [MAX_WIDTH]; 只有在宏定义常量MAX_WIDTH已经被定义的情况下才被编译器考虑,不管它的值是什么。如果它还没有被定义,这一行代码则不会被包括在程序中。

#ifndef起相反的作用:在指令#ifndef和#endif之间的代码只有在某个常量没有被定义的情况下才被编译,例如:

#ifndef MAX_WIDTH
#define MAX_WIDTH 100
#endif
char str [MAX_WIDTH];

这个例子中,如果当处理到这段代码的时候MAX_WIDTH还没有被定义,则它会被定义为值100.而如果它已经被定义了,那么它会保持原值(因为#define语句这一行不会被执行)。

指令#if,#else和#elif(elif = else if)用来使得其后面所跟的程序部分只有在特定条件下才被编译。这些条件只能够是常量表达式,例如:

#if MAX_WIDTH> 200
#undef MAX_WIDTH
#define MAX_WIDTH 200

#elsif MAX_WIDTH <50
#undef MAX_WIDTH
#define MAX_WIDTH 50

#else
#undef MAX_WIDTH
#define MAX_WIDTH 100
#endif

char str [MAX_WIDTH];

注意看这一连串的指令#if,#elsif和#else是怎样以#endif结尾的。

 

#线

 

当我们编译一段程序的时候,如果有错误发生,编译器会在错误前面显示出错文件的名称以及文件中的第几行发生的错误。指令#line可以使我们对这两点进行控制,也就是。说当出错时显示文件中的行数以及我们希望显示的文件名它的格式是:

#line number "filename"

这里号码将会会给下一行的新行数。它后面的行数从这一点逐个递增。

filename是一个可选参数,用来替换自此行以后出错时显示的文件名,直到有另外一个#line指令替换它或直到文件的末尾。例如:

#line 1“赋值变量”
int a?;

这段代码将会产生一个错误,显示为在文件“赋值变量”,第1行。

#错误

这个指令将中断编译过程并返回一个参数中定义的出错信息,例如:

#ifndef __cplusplus
#error需要一个C ++编译器
#endif

这个例子中如果__cplusplus没有被定义就会中断编译过程。

#包括

这个指令我们已经见到很多次。当预处理器找到一个#include指令时,它用指定文件的全部内容替换这条语句。声明包含一个文件有两种方式:

#include "file"
#include <file>

两种表达的唯一区别是编译器应该在什么路经下寻找指定的文件。第一种情况下,文件名被写在双引号中,编译器首先在包含这条指令的文件所在的目录下进行寻找,如果找不到指定文件,编译器再到被配置的默认路径下(也就是标准头文件路径下)进行寻找

如果文件名是在尖括号<>中,编译器会直接到默认标准头文件路径下寻找。

 

的#pragma

 

这个指令是用来对编译器进行配置的,针对你所使用的平台和编译器而有所不同。要了解更多信息,请参考你的编译器手册。

如果你的编译器不支持某个的#pragma的特定参数,这个参数会被忽略,不会产生出错。

 

预定义的宏名称(预定义的宏名称)

以下宏名称在任何时候都是定义好的:

__线__整数值,表示当前正在编译的行在源文件中的行数。
__文件__字符串,表示被编译的源文件的文件名。
__日期__一个格式为“Mmm dd yyyy”的字符串,存储编译开始的日期。
__时间__一个格式为“hh:mm:ss”的字符串,存储编译开始的时间。
__cplusplus整数值,所有C ++编译器都定义了这个常量为某个值。如果这个编译器是完全遵守C ++标准的,它的值应该等于或大于199711L,具体值取决于它遵守的是哪个版本的标准。

 

例如:

 

// 标准宏名称
#include <iostream>
using namespace std;

int main()
{
  cout << "This is the line number " 
       << __LINE__;
  cout << " of file " << __FILE__ 
       << ".\n";
  cout << "Its compilation began " 
       << __DATE__;
  cout << " at " << __TIME__ << ".\n";
  cout << "The compiler gives a "
       <<"__cplusplus value of " 
       << __cplusplus;
  return 0;
}

 

打印如下:

在这儿说一下宏里面的东西吧

最简单的\就是当前宏的定义除了本行下面还有,告诉编译器后面的一起处理
#define OUT(name) printf(#name);

以这个为例其中的#name之前的#就表示把name格式化为字符串
#define T(name) Class## name

这里的## name 中的##就是连接符的意思,Class和可变字符name连接成一个字符串
 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值