吴裕雄--天生自然C++语言学习笔记:C++ 预处理器
预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。
所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。
C++ 还支持很多预处理指令,比如 #include、#define、#if、#else、#line 等
#define 预处理指令用于创建符号常量。该符号常量通常称为宏,指令的一般
形式是:
#define macro-name replacement-text
当这一行代码出现在一个文件中时,在该文件中后续出现的所有宏都将会在程序编译之前被替换为 replacement-text。
#include <iostream>
using namespace std; #define PI 3.14159 int main ()
{ cout << "Value of PI :" << PI << endl; return ;
}
预处理的结果。假设源代码文件已经存在,接下来使用 -E 选项进行编译,并把结果重定向到 test.p。现在,如果您查看 test.p 文件,将会看到它已经包含大量的信息,而且在文件底部的值被改为如下:
$ gcc -E test.cpp > test.p ...
int main ()
{ cout << "Value of PI :" << 3.14159 << endl; return ;
}
可以使用 #define 来定义一个带有参数的宏,如下所示:
#include <iostream>
using namespace std; #define MIN(a,b) (a<b ? a : b) int main ()
{
int i, j;
i = ;
j = ;
cout <<"较小的值为:" << MIN(i, j) << endl; return ;
}
有几个指令可以用来有选择地对部分程序源代码进行编译。这个过程被称为条件编译。
条件预处理器的结构与 if 选择结构很像。请看下面这段预处理器的代码: #ifdef NULL
#define NULL 0
#endif
可以只在调试时进行编译,调试开关可以使用一个宏来实现,如下所示:
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
如果在指令 #ifdef DEBUG 之前已经定义了符号常量 DEBUG,则会对程序中的 cerr 语句进行编译。可以使用 #if 0 语句注释掉程序的一部分,如下所示:
#if 0
不进行编译的代码
#endif
#include <iostream>
using namespace std;
#define DEBUG #define MIN(a,b) (((a)<(b)) ? a : b) int main ()
{
int i, j;
i = ;
j = ;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif #if 0
/* 这是注释部分 */
cout << MKSTR(HELLO C++) << endl;
#endif cout <<"The minimum is " << MIN(i, j) << endl; #ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return ;
}
# 和 ## 预处理运算符在 C++ 和 ANSI/ISO C 中都是可用的。# 运算符会把 replacement-text 令牌转换为用引号引起来的字符串。
#include <iostream>
using namespace std; #define MKSTR( x ) #x int main ()
{
cout << MKSTR(HELLO C++) << endl; return ;
}
## 运算符用于连接两个令牌。下面是一个实例:
#define CONCAT( x, y ) x ## y
当 CONCAT 出现在程序中时,它的参数会被连接起来,并用来取代宏。例如,程序中 CONCAT(HELLO, C++) 会被替换为 "HELLO C++",如下面实例所示。
#include <iostream>
using namespace std; #define concat(a, b) a ## b
int main()
{
int xy = ; cout << concat(x, y);
return ;
}
C++ 提供了下表所示的一些预定义宏:
__LINE__ 这会在程序编译时包含当前行号。
__FILE__ 这会在程序编译时包含当前文件名。
__DATE__ 这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。
__TIME__ 这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。
#include <iostream>
using namespace std; int main ()
{
cout << "Value of __LINE__ : " << __LINE__ << endl;
cout << "Value of __FILE__ : " << __FILE__ << endl;
cout << "Value of __DATE__ : " << __DATE__ << endl;
cout << "Value of __TIME__ : " << __TIME__ << endl; return ;
}
当上面的代码被编译和执行时,它会产生下列结果:
Value of __LINE__ :
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb
Value of __TIME__ : ::
吴裕雄--天生自然C++语言学习笔记:C++ 预处理器的更多相关文章
- 吴裕雄--天生自然C++语言学习笔记:C++ 基本语法
C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互. 对象 - 对象具有状态和行为.例如:一只狗的状态 - 颜色.名称.品种,行为 - 摇动.叫唤.吃.对象是类的实例. 类 - 类可 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 标准库
C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 动态内存
栈:在函数内部声明的所有变量都将占用栈内存. 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存. 可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址.这种运 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 类 & 对象
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计.类是 C++ 的核心特性,通常被称为用户定义的类型. 类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法.类中的 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 日期 & 时间
C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数.为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 <ctime> 头文件. 有四 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 字符串
C++ 提供了以下两种类型的字符串表示形式: C 风格字符串 C++ 引入的 string 类类型 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持.字符串实际上是使用 null 字符 ...
- 吴裕雄--天生自然C++语言学习笔记:C++简介
C++ 是一种中级语言,它是由 Bjarne Stroustrup 于 年在贝尔实验室开始设计开发的.C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言.C++ 可运行于多种平台上,如 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 实例
C++ 实例 - 输出 "Hello, World!" #include <iostream> using namespace std; int main() { co ...
- 吴裕雄--天生自然C++语言学习笔记:C++ STL 教程
C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量.链表.队列.栈. C++ 标准模板库的核心包括以 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ Web 编程
什么是 CGI? 公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的. CGI 规范目前是由 NCSA 维护的,NCSA 定义 CGI 如下: 公共网关接 ...
随机推荐
- 使用anaconda 3安装tensorflow 1.15.0 (win10环境)
0.写在前面 之前其实安装过一次tensorflow,但是由于电脑中毒,重装了系统,把所有的环境全部删除了.之前在博客里转发了一篇别人在win10安装tensorflow的教程,但是版本比较旧了, ...
- sentinel控制台
下载sentinel源码包:https://github.com/alibaba/Sentinel/tree/master,根据自己需要下载不同版本的分支,博主下载得是1.6 下载后解压,然后进入se ...
- Metasploit学习笔记——社会工程学
1.社会工程学攻击案例——伪装木马 Linux命令终端输入命令msfvenom -l payloads用来列出攻击载荷,grep命令用来查询所需要的攻击载荷,条件是windows系统.要有回连至监听主 ...
- jquery获取select选中的文本值
误区: 一直以为jquery获取select中option被选中的文本值,是这样写的: $("#id").text(); //获取所有option的文本值 实际上应该这样: ...
- 在Java中,为什么十六进制数0xFF取反之后对应的十进制数是-256呢?
int number = 0xFF: 字面值是指在程序中无需变量保存,可直接表示为一个具体的数字或字符串的值. 0xFF是一个整数字面值,整数字面值的缺省类型是 int. 我们知道在Java中, in ...
- IOS 3种内省方法
IOS提供了3种内省方法 isKindOfClass 检查当前实例是否为某类及其子类 UIView *b = [UIView new]; //... id a = b; if ([a isMember ...
- ubuntu 怎么更新?ubuntu更新命令及方法
ubuntu 怎么更新?ubuntu更新命令及方法 安装Ubuntu系统后,第一件事就是更新系统源.由于系统安装的默认源地址在英国,作为Ubuntu的主源,国内连接速度非常慢,所以我们要将它换成就近的 ...
- 设备树DTS 学习:2-设备树语法
背景 通过上一讲了解完设备树DTS有关概念,我们这一讲就来基于设备树例程,学习设备树的语法规则. 参考:设备树详解dts.设备树语法详解.设备树使用总结 设备树框架 1个dts文件 + n个dtsi文 ...
- 怎样管理Exchange Server 2013资源邮箱
1. exchange资源邮箱介绍 这次将介绍Exchange Server 2013的资源邮箱相关内容. Exchange Server 2013的资源邮箱包含两类,其一为“会议室邮箱”,另一类是“ ...
- 基于线程池、消息队列和epoll模型实现并发服务器架构
引言 并发是什么?企业在进行产品开发过程中为什么需要考虑这个问题?想象一下天猫的双11和京东的618活动,一秒的点击量就有几十万甚至上百万,这么多请求一下子涌入到服务器,服务器需要对这么多的请求逐个进 ...