C++ "#"的作用和用法
2016-02-20 17:11
519 查看
本系列文章由 @yhl_leo 出品,转载请注明出处。
文章链接: http://blog.csdn.net/yhl_leo/article/details/48879093
1
C/C++ 的宏中,
凡是宏定义里有用
加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的宏就能得到对应的宏参数。
接下来,我们来了解通过预处理指令创建条件编译参数控制代码编译的一些用法。
2
包含头文件的操作,通常有两种格式:
所以,系统头文件一般用
1 相关文件(优先位置,如
2 C系统文件
3 C++ 系统文件
4 其他库的
5 本项目内
3
这里的结构跟常见的
4
在编程时,为了避免头文件重定义,经常使用的就是
除此以外,还有
5
6
文章链接: http://blog.csdn.net/yhl_leo/article/details/48879093
1 #
和##
的作用和用法
C/C++ 的宏中,#的功能是将其后面的宏参数进行字符串化操作,简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。
##连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。
#include <iostream> using namespace std; #define WARN_IF(EXP) if(EXP) cerr << #EXP << endl; #define paster( n ) cout << "token" << #n << " = " << n << endl; #define _CONS(a, b) int(a##+##b) #define _STRI(s) #s void main() { int div = 0; WARN_IF(div == 0); // prints : div == 0 paster(9); // prints : token9 = 9 cout << _CONS(1, 2) << endl; // prints : 3 cout << _STRI(INT_MAX) << endl; // prints : INT_MAX }
凡是宏定义里有用
#或
##的地方宏参数是不会再展开,例如
_STRI(INT_MAX)中的
INT_MAX就不会被展开为2147483647。如果想要使其中的宏参数展开,则需要多加一层中间转换宏:
#define STRI(s) _STRI(s) cout << STRI(INT_MAX) << endl; // prints : 2147483647
加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的宏就能得到对应的宏参数。
接下来,我们来了解通过预处理指令创建条件编译参数控制代码编译的一些用法。
2 #include
的用法
包含头文件的操作,通常有两种格式:#include <header-file> #include "header-file"
<>和
""表示编译器在搜索头文件时的顺序不同:
<>表示从系统目录下开始搜索,然后再搜索PATH环境变量所列出的目录,不搜索当前目录
""是表示从当前目录开始搜索,然后是系统目录和PATH环境变量所列出的目录。
所以,系统头文件一般用
<>,用户自己定义的则可以使用
"",加快搜索速度。除此外,写代码多了就会发现,有些头文件之间的相互包含是有隐藏依赖关系的,一定要加以注意。Google C++ Style Guide中也强调使用标准的头文件包含顺序可增强可读性, 避免隐藏依赖:
1 相关文件(优先位置,如
dir2/foo2.h)
2 C系统文件
3 C++ 系统文件
4 其他库的
.h文件
5 本项目内
.h文件
3 #if
,#elif
,#else
,#endif
用法
// structure 1 #if constant_expression #else #endif // structure 2 #if constant_expression #elif constant_expression #endif
这里的结构跟常见的
if...else和
if...else if...else语句类似,当
#if后的条件为非零(true)时,编译
#if和
#else或
#elif之间的代码,否则编译
#else和
#endif之间的代码(或者判断
#elif后的条件是否非零(true),决定是否编译
#elif和
#endif之间的代码)。
#if 1 cout << "Hello world!" << endl; #else cout << "Nice to meet you!" << endl; #endif // prints : Hello world!
#if 1 cout << "Hello world!" << endl; #elif 1 cout << "Nice to meet you!" << endl; #endif // prints: Hello world! // Nice to meet you!
4 #define
,#undef
,#ifdef
,#ifndef
用法
#define是大家都常见的宏定义方法,用法结构为:
// #define identifier replacement-code #define PI 3.1415926 #define ADD(x,y) (x + y)
#undef顾名思义,就是从该处取消前面已经定义的宏,如果标识符当前没有被定义称为一个宏名称,就会忽略该指令:
// #undef identifier #undef PI
#ifdef和
#ifndef含义相反,前者含义为如果定义了该宏,则编译相应代码;后者则为如果没有定义该宏,则编译相应代码。通用结构为:
/* * #ifdef identifier * #else or #elif * #endif **/ #define DEBUG #ifdef DEBUG cout << "This is a debug message." << endl; #endif // prints : This is a debug message. /* * #ifndef identifier * #else or #elif * #endif **/ #ifndef DEBUG cout << "This is a debug message." << endl; #endif // prints nothing
在编程时,为了避免头文件重定义,经常使用的就是
#define配合条件编译解决:
#ifndef MY_HEADER_FILE_H #define MY_HEADER_FILE_H // ... class MyHeaderFile { // .... }; #endif // MY_HEADER_FILE_H
除此以外,还有
#pragma once的用法,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次。(在所有的预处理指令中,
#pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作,本文不多讲述。)
5 #line
用法
#line命令是用于更改
__LINE__和
__FILE__变量的值。
__FILE__和
__LINE__描述被读取的当前文件和所在行数。
// #line line-number filename int main() { #line 10 "main.cpp" cout << __FILE__ << " " << __LINE__ << endl; } // prints : main.cpp 10
6 #error
用法
#error会直接导致程序停止编译并输出指定的错误信息:
// #error message #ifndef VERSION #error Version number not specified. #endif // The compiler will halt compiling and return with the specified error message: // fatal error C1189: #error : Version number not specified.
相关文章推荐
- utilities(C++)——Null类的设计
- C++中map的使用详解说明
- c++异常捕获
- C/C++内存问题检查利器
- c++笔试题总结1
- C++内存管理
- c++中的栈和队列
- [C++]虚函数与纯虚函数
- C语言之实现随机数产生算法
- C语言之实现随机数产生算法
- C语言之实现随机数产生算法
- 为什么C++编译器不能支持对模板的分离式编译
- servlet中Java调用C++,JNI
- C++语言文件的定义与操作
- 1020. Tree Traversals (25)
- C语言union 关键字与大小端模式
- 【C语言】文件常用读写操作(含读取学生信息示例)
- [UVA1368]DNA Consensus String
- c语言入门之项目2.3——利息计算器
- C++中,什么叫类,结构,联合?