C++ 基础

C++ 主页 C++ 概述 C++ 环境设置 C++ 基本语法 C++ 注释 C++ Hello World C++ 省略命名空间 C++ 标记 C++ 常量/字面量 C++ 关键字 C++ 标识符 C++ 数据类型 C++ 数字数据类型 C++ 字符数据类型 C++ 布尔数据类型 C++ 变量类型 C++ 变量作用域 C++ 多变量 C++ 基本输入/输出 C++ 修饰符类型 C++ 存储类 C++ 数字 C++ 枚举 C++ 枚举类 C++ 引用 C++ 日期和时间

C++ 运算符

C++ 运算符 C++ 算术运算符 C++ 关系运算符 C++ 逻辑运算符 C++ 位运算符 C++ 赋值运算符 C++ sizeof 运算符 C++ 条件运算符 C++ 逗号运算符 C++ 成员运算符 C++ 强制类型转换运算符 C++ 指针运算符 C++ 运算符优先级 C++ 一元运算符

C++ 控制语句

C++ 决策语句 C++ if 语句 C++ if else 语句 C++ 嵌套 if 语句 C++ switch 语句 C++ 嵌套 switch语句 C++ 循环类型 C++ while 循环 C++ for 循环 C++ do while 循环 C++ Foreach 循环 C++ 嵌套循环 C++ break 语句 C++ continue 语句 C++ goto 语句

C++ 字符串

C++ 字符串 C++ 循环遍历字符串 C++ 字符串长度 C++ 字符串连接 C++ 字符串比较

C++ 函数

C++ 函数 C++ 多函数参数 C++ 递归函数 C++ 返回值 C++ 函数重载 C++ 函数重写 C++ 默认参数

C++ 数组

C++ 数组 C++ 多维数组 C++ 指向数组的指针 C++ 将数组传递给函数 C++ 从函数返回数组

C++ 结构 &联合

C++ 结构 C++ 联合

C++ 指针

C++ 指针 C++ 解引用 C++ 修改指针

C++ 类和对象

C++ 面向对象 C++ 类 &对象 C++ 类成员函数 C++ 类访问修饰符 C++ 静态类成员 C++ 静态数据成员 C++ 静态成员函数 C++ 内联函数 C++ this 指针 C++ 友元函数 C++ 指向类的指针

C++ 构造函数

C++ 构造函数 &析构函数 C++ 默认构造函数 C++ 参数化构造函数 C++ 复制构造函数 C++ 构造函数重载 C++ 带默认参数的构造函数 C++ 委托构造函数 C++ 构造函数初始化列表 C++ 使用构造函数动态初始化

C++ 继承

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++ Lambda 表达式 C++ unordered_multiset

C++ 实用资源

C++ 问答 C++ 快速指南 C++ 速查表 C++ STL 教程 C++ 标准库 C++ 实用资源 C++ 讨论


C++ 预处理器

预处理器指令是一些指令,它们指示编译器在实际编译开始之前对信息进行预处理。

所有预处理器指令都以 # 开头,并且一行中预处理器指令前只能出现空格。预处理器指令不是 C++ 语句,因此它们不以分号 (;) 结尾。

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

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

#define 预处理器指令

#define 预处理器指令创建符号常量。这个符号常量被称为,其指令的一般形式为:-

#define macro-name 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,它会包含大量信息,并且在底部,您会发现替换的值如下所示 -

$gcc -E test.cpp > test.p

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

Function-Like Macros

You can use #define to define a macro which will take argument as follows −

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

If we compile and run above code, this would produce the following result −

The minimum is 30

Conditional Compilation

There are several directives, which can be used to compile selective portions of your program's source code. This process is called conditional compilation.

The conditional preprocessor construct is much like the if selection structure. Consider the following preprocessor code −

#ifndef NULL
   #define NULL 0
#endif

You can compile a program for debugging purpose. You can also turn on or off the debugging using a single macro as follows −

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

This causes the cerr statement to be compiled in the program if the symbolic constant DEBUG has been defined before directive #ifdef DEBUG. You can use #if 0 statment to comment out a portion of the program as follows −

#if 0
   code prevented from compiling
#endif

Let us try the following example −

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

If we compile and run above code, this would produce the following result −

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

The # and ## Operators

The # and ## preprocessor operators are available in C++ and ANSI/ISO C. The # operator causes a replacement-text token to be converted to a string surrounded by quotes.

Consider the following macro definition −

#include <iostream>
using namespace std;

#define MKSTR( x ) #x

int main () {

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

   return 0;
}

If we compile and run above code, this would produce the following result −

HELLO C++

Let us see how it worked. It is simple to understand that the C++ preprocessor turns the line −

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

Above line will be turned into the following line −

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

The ## operator is used to concatenate two tokens. Here is an example −

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

When CONCAT appears in the program, its arguments are concatenated and used to replace the macro. For example, CONCAT(HELLO, C++) is replaced by "HELLO C++" in the program as follows.

#include <iostream>
using namespace std;

#define concat(a, b) a ## b
int main() {
   int xy = 100;
   
   cout << concat(x, y);
   return 0;
}

If we compile and run above code, this would produce the following result −

100

Let us see how it worked. It is simple to understand that the C++ preprocessor transforms −

cout << concat(x, y);

Above line will be transformed into the following line −

cout << xy;

Predefined C++ Macros

C++ provides a number of predefined macros mentioned below −

Sr.No Macro & Description
1

__LINE__

This contains the current line number of the program when it is being compiled.

2

__FILE__

This contains the current file name of the program when it is being compiled.

3

__DATE__

This contains a string of the form month/day/year that is the date of the translation of the source file into object code.

4

__TIME__

This contains a string of the form hour:minute:second that is the time at which the program was compiled.

Let us see an example for all the above macros −

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

If we compile and run above code, this would produce the following result −

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48