C++ 包含头文件 和 宏的使用 和 条件编译
#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。
该命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义。
- #define <宏名> <字符串>
- 例: #define PI 3.1415926
- #define <宏名> (<参数表>) <宏体>
- 例: #define A(x) x
为了能够真正理解#define的作用,让我们来了解一下对C语言源程序的处理过程。当我们在一个集成的开发环境如Turbo C中将编写好的源程序进行编译时,实际经过了预处理、编译、汇编和连接几个过程。其中预处理器产生编译器的输出,它实现以下的功能:
(1)文件包含
可以把源程序中的#include 扩展为文件正文,即把包含的.h文件找到并展开到#include 所在处。
(2)条件编译
预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中的某部分包含进来或排除在外,通常把排除在外的语句转换成空行。
(3)宏展开
预处理器将源程序文件中出现的对宏的引用展开成相应的宏 定义,即本文所说的#define的功能,由预处理器来完成。
经过预处理器处理的源程序与之前的源程序有所有不同,在这个阶段所进行的工作只是纯粹的替换与展开,没有任何计算功能,所以在学习#define命令时只要能真正理解这一点,这样才不会对此命令引起误解并误用。
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
#ifdef 标识符 程序段1 #else 程序段2 #endif
它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。 其中#else部分也可以没有,即: #ifdef 程序段1 #denif
在头文件中使用#ifdef和#ifndef是非常重要的,可以防止双重定义的错误。如你在头文件aaa.h中定义了一个类aaa如下: class aaa { }; 如果两次#include "aaa.h"(不见得是直接,也有可能两个不同的头文件中都包含了这个头文件)就会出错,因为相同的类不能定义两次。把aaa.h稍做修改: #ifndef _aaa_ #define _aaa_ class aaa { }; #endif 就可以避免这样的问题。因为当你已经包含过这个文件,_aaa_就会有了定义,那么#ifndef的条件为假,就不会再执行后面的类定义了。
#ifdef和#endif必须成对使用。 从理论上讲可以出现在任何地方(头文件和实现文件中) 通常为了防止头文件被多次包含,在头文件中使用是必须的: 如:#ifndef MY_HEAD_H //头文件开头,名字是任意的,注意不要和其它头文件冲突 头文件声明 #endif //头文件结尾
有时候,在b.h中会include "a.h" ,在"c.h"中会include "b.h"及include"a.h", 这时,如果不用ifndef/endif,就会包含两次a.h,产生错误。
还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:
#ifndef <标识> #define <标识>
...... ......
#endif
<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h
#ifndef _STDIO_H_ #define _STDIO_H_
......
#endif
2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。
#ifndef AAA #define AAA ... int i; ... #endif 里面有一个变量定义,在vc中链接时就出现了重复定义的错误,而在c中成功编译。
C++ 包含头文件 和 宏的使用 和 条件编译的更多相关文章
- 头文件的宏定义#ifndef测试
一.入题 在头文件的书写中,都加入了如下内容: #ifndef __头文件名_H #define __头文件名_H #endif 曾经在书中看到的解释是“防止重复定义”,今天突然想到为什么是这样的解释 ...
- ZT 头文件包含其实是一想很烦琐的工作 第一个原则应该是,如果可以不包含头文件
当出现访问类的函数或者需要确定类大小的时候,才需要用头文件(使用其类定义) http://blog.csdn.net/clever101/article/details/4751717 看到这个 ...
- glibc头文件和宏定义
头文件没啥好说的,无非就是" "和< >的区别,这估计只要是学过C/C++的人都明白.现在的编译器对头文件的包含顺序没有要求,但老的C实现则不一样.当然,我们现在无需关 ...
- include包含头文件的语句中,双引号和尖括号的区别是什么?
include包含头文件的语句中,双引号和尖括号的区别是什么? #include <> 格式:引用标准库头文件,编译器从标准库目录开始搜索 尖括号表示只在系统默认目录或者括号内的路径查找 ...
- C/C++不同文件夹下包含头文件的方法及#include的使用
转自:http://blog.sina.com.cn/s/blog_6e0693f70100so42.html 本文主要介绍了如何不同文件夹下使用预处理器指示符#include. 假设我们有如下一个工 ...
- C++中#include包含头文件带 .h 和不带 .h 的区别
C++中#include包含头文件带 .h 和不带 .h 的区别? 如 #include <iostream> 和 #include <iostream.h> 包含的东西有哪些 ...
- include包含头文件的语句中,双引号和尖括号的区别
include包含头文件的语句中,双引号和尖括号的区别 #include <>格式:引用标准库头文件,编译器从标准库目录开始搜索 #incluce ""格式:引用非 ...
- c++包含头文件好还是重新定义好
A.h struct A { int a; int b; }; B.cpp 在B.cpp里面用到这个结构体 有两种方法 .自己定义一个一模一样的结构体 struct A { }; .包含A.h头文件 ...
- 在.h和.cpp中包含头文件的区别
1.在.h中包含头文件,是为了声明一系列这个头文件的变量等,可能会产生重复包含的问题: 2.在.cpp中包含头文件只是为了实现这个头文件或者使用其中的方法,不会有重复包含的问题,所以尽量在源文件中包含 ...
随机推荐
- [c language] getopt
getopt(分析命令行参数) 相关函数表头文件 #include<unistd.h>定义函数 int getopt(int argc,char * ...
- static的用法解析
PHP中static变量的使用范围要更广一些,我们不仅可以在类,方法或变量前面添加static修饰符,我们甚至还能给函数内部变量添加static关键字.添加了static修饰符的变量即使在该函数执行完 ...
- Ubuntu中找到并杀死僵尸进程
Ubuntu中产生zombie进程让人很懊恼啊.Windows中在任务管理器里直接找到无响应的进程并结束他就行了,但是ubuntu中需要用命令去解决. System information as of ...
- SQL Server 查看空间使用情况的 5 种方法
解决方法: 方法 1.sp_spaceused 方法 2.dbcc sqlperf 方法 3.dbcc showfilestats 方法 4.dbcc showcontig 方法 5.sys.dm_d ...
- Java 学习 第一篇
1:Java文档注释:使用javadoc工具可以提取程序中文档注释来生成API文档:javadoc命令的基本用法:javadoc 选项 java源文件/包javadoc -d {} -windowti ...
- USB枚举过程的详细流程
USB枚举过程的详细流程 用户将一个USB设备插入USB端口,主机为端口供电,设备此时处于上电状态.主机检测设备.1>Hub使用中断通道将事件报告给Host.2>Host发送Get_Por ...
- Application.HookMainWindow完全替代了原来的窗口过程(但是好像也会继续传递)
unit HookMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo ...
- Silverlight 结合ArcGis 在地图上画线
原文 http://www.dotblogs.com.tw/justforgood/archive/2012/05/10/72085.aspx 先来看看完成后的画面,我从桃园画到高雄,再由高雄画到香港 ...
- python选择排序实现与C选择排序实现
python代码: #coding=utf-8 if __name__=="__main__": arr=[3,2,1,7,11,4,5,8] print "Before ...
- FlashBack-SCN-TIMESTAMP
一.基于时间(as of timestamp)的flashback1.创建表create table flash_tab(id,vl) as select rownum,oname from ( se ...