【C++学习笔记】关于预处理器的几个问题
2017-02-24 14:17
375 查看
C/C++预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序。预处理器指令以#开头,末尾没有分号。预处理命令不是C/C++的组成部分。C/C++的编译系统的过程为预处理->编译->链接。
预处理过程的主要常用功能有:文件包含、宏替换、条件编译等。
尖括号的形式表示被包含的文件在系统目录,搜索时先从系统标准库进行搜索。对于系统提供的头文件,应该用尖括号的形式。
双引号的形式表示被包含的文件不一定在系统目录中,在双引号的形式下,可以指出文件的路径和文件名(./表示当前目录,../表示当前目录的父目录),若未给出,则默认在当前目录的文件夹,也先从当前目录文件夹查找,找不到再到其他目录查找。
用一个指定的标识符来代替一段代码序列。标识符成为宏定义名。
这时宏展开进行宏名与宏参数的替换。
宏名的作用域不受分程序结构的影响。如果需要终止宏名的作用域,可以用预处理指令#undef加上宏名。
宏替换只作代码字符序列的替换工作,不作任何语法的检查,也不作任何的中间计算,一切其它操作都要在替换完后才能进行。如果宏定义不当,错误要到预处理之后的编译阶段才能发现。
源代码中的宏名和宏定义代码序列中的宏形参名必须是标识符才会被替换,即只替换标识符,不替换别的东西,像注释、字符串常量以及标识符内出现的宏名或宏形参名则不会被替换。
条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。
最常见的处理方法就是在头文件的开头加上条件编译语句。
参考博文:http://www.cnblogs.com/lidabo/archive/2012/08/27/2658909.html
预处理过程的主要常用功能有:文件包含、宏替换、条件编译等。
1. 文件包含
用于文件包含的预处理指令有两种形式:#include <xxx.h> #include "xxx.h"
尖括号的形式表示被包含的文件在系统目录,搜索时先从系统标准库进行搜索。对于系统提供的头文件,应该用尖括号的形式。
双引号的形式表示被包含的文件不一定在系统目录中,在双引号的形式下,可以指出文件的路径和文件名(./表示当前目录,../表示当前目录的父目录),若未给出,则默认在当前目录的文件夹,也先从当前目录文件夹查找,找不到再到其他目录查找。
2. 宏替换
1.宏定义
宏定义的作用一般是用一个简短的名字代替较长的代码序列。宏定义包括无参数宏定义与带参数宏定义两种。a. 无参数宏定义
#define 标识符 代码序列
用一个指定的标识符来代替一段代码序列。标识符成为宏定义名。
b. 带参数宏定义
#define 标识符(参数) 代码序列 #define SQR(x) x*x;
这时宏展开进行宏名与宏参数的替换。
2. 宏的作用域
宏定义的有效范围称为宏名的作用域,宏名的作用域从宏定义的结束处开始到其所在的源代码文件末尾。宏名的作用域不受分程序结构的影响。如果需要终止宏名的作用域,可以用预处理指令#undef加上宏名。
3. 宏展开
预处理器在处理宏定义时,会对宏进行展开(即宏替换)。宏替换首先将源文件中在宏定义随后所有出现的宏名均用其所代表的代码序列替换之,如果是带参数宏则接着将代码序列中的宏形参名替换为宏实参名。宏替换只作代码字符序列的替换工作,不作任何语法的检查,也不作任何的中间计算,一切其它操作都要在替换完后才能进行。如果宏定义不当,错误要到预处理之后的编译阶段才能发现。
源代码中的宏名和宏定义代码序列中的宏形参名必须是标识符才会被替换,即只替换标识符,不替换别的东西,像注释、字符串常量以及标识符内出现的宏名或宏形参名则不会被替换。
3. 条件编译指令
一般情况下,在进行编译时对源程序中的每一行都要编译,但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,如果不满足这个条件,就不编译这部分内容,这就是条件编译。条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。
最常见的处理方法就是在头文件的开头加上条件编译语句。
#ifndef _ALLOC_H_ #define _ALLOC_H_ class alloc { ... }; #endif
参考博文:http://www.cnblogs.com/lidabo/archive/2012/08/27/2658909.html
相关文章推荐
- JavaWeb技术学习笔记(2)-关于tomcat的几个问题
- C++学习笔记001-关于cin的几个用法
- 学习笔记-----关于C++中类的成员函数可以访问私有成员的问题
- Inside The C++ Object Model 学习笔记 -- 关于对象
- 关于asp.net 2.0 入门学习之“GlobalResources与Callback问题”的笔记
- 关于 TerminateProcess函数 在c++的进程中的学习而发现VS2008的编译安全问题
- 学习笔记一(一个关于TextOut和Invalidate的问题)
- 【个人学习笔记8之--关于OVER子句 多属性的比较 PIVOT 聚合问题】
- java学习笔记,试用初学者,第二节,关于内存地址分配问题
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(3) 最大子序列和问题
- Effective C++ (5) 几个关于数组的问题
- 关于SQLServer2005的学习笔记——多触发器执行问题
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)(转帖)
- C++学习笔记(8)——继承中的二义性问题和虚基类
- 关于C++学习的几个建议
- 关于asp.net 2.0 入门学习之“GlobalResources与Callback问题”的笔记
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)
- 【笔记】关于NIOS II PIO的几个问题
- [学习笔记]学C#遇到的几个问题