主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
C++

C++ 基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

C++ 字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

C++ 函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

C++ 面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

C++ 高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

基础

C++ 主页
C++ 概述
C++ 环境
C++ 基本语法
C++ 注释
C++ 数据类型
C++ Hello, World
C++ 省略命名空间
C++ 数值类型
C++ 字符类型
C++ 布尔类型
C++ 变量
C++ 作用域
C++ 多个变量
C++ 输入输出基础
C++ 常量/文字
C++ 修饰符类型
C++ 存储类别
C++ 操作符
C++ 决策结构
C++ 循环结构
C++ foreach 循环
C++ 数字
C++ 数组
C++ 指针
C++ 枚举类型
C++ 引用变量
C++ 日期与时间
C++ 结构体
C++ 联合类型

字符串

C++ 字符串
C++ 字符串长度
C++ 字符串连接

函数

C++ 函数
C++ 多参数函数
C++ 递归
C++ return 语句
C++ 函数重载
C++ 函数重写

面向对象

C++ 面向对象
C++ 类和对象
C++ 多重继承
C++ 多层次继承
C++ 继承
C++ 重载
C++ 多态性
C++ 抽象
C++ 封装
C++ 接口

高级

C++ 文件和流
C++ 异常处理
C++ 动态内存
C++ 命名空间
C++ 模板
C++ 预处理器
C++ 信号量
C++ 多线程
C++ Web 编程
C++ 高级概念

C++ 预处理器


上一章 下一章

一. 预处理器

预处理器指令是为编译器提供指令,以便在实际编译开始之前对信息进行预处理。所有的预处理器指令以#开头,且在指令行的前面只能有空白字符。预处理器指令不是C++语句,因此它们不以分号;结束。

在所有的示例中,您已经见过#include指令。此宏用于将头文件包含到源文件中。

C++支持多种预处理器指令,例如#include、#define、#if、#else、#line等。让我们来看一些重要的指令。

二. #define 预处理器

#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 0;
}

如果我们编译该代码并使用-E选项进行预处理,并将结果重定向到test.p,检查test.p文件的底部,我们会看到宏被替换后的内容如下:

int main () {
   cout << "Value of PI :" << 3.14159 << endl; 
   return 0;
}

三. 函数式宏

您可以使用#define定义带参数的宏,如下所示:

#include <iostream>
using namespace std;

#define MIN(a,b) (((a)<(b)) ? a : b)

int main () {
   int i, j;
   
   i = 100;
   j = 30;
   
   cout <<"The minimum is " << MIN(i, j) << endl;
   return 0;
}

如果我们编译并运行上述代码,结果将是:

The minimum is 30

四. 条件编译

有几个指令可用于有选择地编译程序的某些部分,这个过程称为条件编译。条件预处理器结构与if选择结构类似。请看下面的预处理器代码:

#ifndef NULL
   #define NULL 0
#endif

您可以通过一个宏打开或关闭调试功能,如下所示:

#ifdef DEBUG
   cerr <<"Variable x = " << x << endl;
#endif

这段代码会在编译时加入cerr语句,前提是之前定义了DEBUG。您也可以使用#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 = 100;
   j = 30;

#ifdef DEBUG
   cerr <<"Trace: Inside main function" << endl;
#endif

#if 0
   /* This is commented part */
   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 0;
}

编译并运行该代码的结果如下:

The minimum is 30
Trace: Inside main function
Trace: Coming out of main function

五. # 和 ## 操作符

C++和ANSI/ISO C中提供了#和##预处理器操作符。#操作符会将替换文本转换为带引号的字符串。例如:

#include <iostream>
using namespace std;

#define MKSTR( x ) #x

int main () {
   cout << MKSTR(HELLO C++) << endl;
   return 0;
}

编译并运行上述代码的结果是:

HELLO C++

这是因为预处理器将以下代码:

cout << MKSTR(HELLO C++) << endl;

转化为:

cout << "HELLO C++" << endl;

##操作符用于连接两个标记。如下所示:

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

例如,CONCAT(HELLO, C++)在程序中被替换为"HELLO C++"。

六. 预定义C++宏

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

序号 宏名 描述
1 LINE 包含当前编译时的行号。
2 FILE 包含当前编译的文件名。
3 DATE 包含源文件编译为目标代码时的日期,格式为月/日/年。
4 TIME 包含编译程序的时间,格式为时:分:秒。

来看一个包含这些宏的例子:

#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 0;
}

编译并运行该代码的结果如下:

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图