C++ 高级篇(五)—— 预处理指令
来源:互联网 发布:矢量图软件哪个好 编辑:程序博客网 时间:2024/05/22 09:03
预处理指令是我们写在程序代码中的给预处理器(preprocessor)的 命令,而不是程序本身的语句。预处理器在我们编译一个C++程序时由编译器自动执行,它负责控制对程序代码的第一次验证和消化。
所有这些指令必须写在单独的一行中,它们不需要加结尾的分号;。
#define
在这个教程的开头我们已经提到了一种预处理指令: #define ,可以被用来生成宏定义常量(defined constantants 或 macros),它的形式是:
#define name value
它的作用是定义一个叫做name 的宏定义,然后每当在程序中遇到这个名字的时候,它就会被value代替,例如:
char str1[MAX_WIDTH];
char str2[MAX_WIDTH];
它定义了两个最多可以存储100个字符的字符串。
#define 也可以被用来定义宏函数:
int x=5, y;
y = getmax(x,2);
这段代码执行后y 的值为5 。
#undef
#undef 完成与 #define相反的工作,它取消对传入的参数的宏定义:
char str1[MAX_WIDTH];
#undef MAX_WIDTH
#define MAX_WIDTH 200
char str2[MAX_WIDTH];
#ifdef, #ifndef, #if, #endif, #else and #elif
这些指令可以使程序的一部分在某种条件下被忽略。
#ifdef 可以使一段程序只有在某个指定常量已经被定义了的情况下才被编译,无论被定义的值是什么。它的操作是:
// code here
#endif
例如:
char str[MAX_WIDTH];
#endif
在这个例子中,语句char str[MAX_WIDTH]; 只有在宏定义常量MAX_WIDTH 已经被定义的情况下才被编译器考虑,不管它的值是什么。如果它还没有被定义,这一行代码则不会被包括在程序中。
#ifndef 起相反的作用:在指令#ifndef 和 #endif 之间的代码只有在某个常量没有被定义的情况下才被编译,例如:
#define MAX_WIDTH 100
#endif
char str[MAX_WIDTH];
这个例子中,如果当处理到这段代码的时候MAX_WIDTH 还没有被定义,则它会被定义为值100。而如果它已经被定义了,那么它会保持原值 (因为#define 语句这一行不会被执行) 。
指令#if, #else 和 #elif (elif = else if) 用来使得其后面所跟的程序部分只有在特定条件下才被编译。这些条件只能够是常量表达式,例如:
#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 可以使我们对这两点进行控制,也就是说当出错时显示文件中的行数以及我们希望显示的文件名。它的格式是:
#line number "filename"
这里number 是将会赋给下一行的新行数。它后面的行数从这一点逐个递增。
filename 是一个可选参数,用来替换自此行以后出错时显示的文件名,直到有另外一个#line指令替换它或直到文件的末尾。例如:
int a?;
这段代码将会产生一个错误,显示为在文件"assigning variable", line 1 。
#error
这个指令将中断编译过程并返回一个参数中定义的出错信息,例如:
#error A C++ compiler is required
#endif
这个例子中如果 __cplusplus 没有被定义就会中断编译过程。
#include
这个指令我们已经见到很多次。当预处理器找到一个#include 指令时,它用指定文件的全部内容替换这条语句。声明包含一个文件有两种方式:
#include "file"
#include <file>
两种表达的唯一区别是编译器应该在什么路经下寻找指定的文件。第一种情况下,文件名被写在双引号中,编译器首先在包含这条指令的文件所在的目录下进行寻找,如果找不到指定文件,编译器再到被配置的默认路径下(也就是标准头文件路径下)进行寻找。
如果文件名是在尖括号 <> 中,编译器会直接到默认标准头文件路径下寻找。
#pragma
这个指令是用来对编译器进行配置的,针对你所使用的平台和编译器而有所不同。要了解更多信息,请参考你的编译器手册。
如果你的编译器不支持某个#pragma的特定参数,这个参数会被忽略,不会产生出错。
预定义的宏名称 (Predefined macro names)
以下宏名称在任何时候都是定义好的:
例如:
// 标准宏名称#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;}This is the line number 7 of file /home/jay/stdmacronames.cpp.
Its compilation began Nov 1 2005 at 10:12:29.
The compiler gives a __cplusplus value of 1
- C++ 高级篇(五)—— 预处理指令
- C++ 高级篇(五)—— 预处理指令
- 黑马程序员——5、C语言(预处理指令)
- C语言基础——预处理指令
- C++---基础篇(预处理程序指令)
- 【C语言】预处理指令—宏定义
- 【C语言】预处理指令—条件编译
- 【C语言】预处理指令—文件包含
- C/C++: 预处理指令
- 黑马程序员——C语言——预处理指令
- 黑马程序员——C语言——预处理指令
- C/C++ 预处理程序参考——#import 指令
- 黑马程序员—C语言—预处理指令
- 黑马程序员—C语言—预处理指令及补充
- 黑马程序员——12-C语言之预处理指令
- 黑马程序员——C语言---预处理指令
- 黑马程序员——C语言笔记之预处理指令
- 黑马程序员——C语言中的预处理指令
- Flexbox布局(2)
- 剑指Offer----面试题八:旋转数组的做小数字
- HTTP请求报文和HTTP响应报文
- iOS开发的几个小问题(二)
- flume 简单案例 将一个节点的中一个日志文件的动态变化 在 另一个节点的终端输出
- C++ 高级篇(五)—— 预处理指令
- OC 类方法的调用
- 3.矩阵分析与应用
- Hibernate级联查询实体关系映射
- C++ 标准函数库 —— 文件的输入输出 (Input/Output with files)
- 深入理解散列表(哈希表)
- 数据库的关系代数六大基本操作符
- MyEclipse无法启动(闪退)的一种解决
- LeetCode 98. Validate Binary Search Tree(校验二叉搜索树)