头文件没啥好说的,无非就是" "和< >的区别,这估计只要是学过C/C++的人都明白。现在的编译器对头文件的包含顺序没有要求,但老的C实现则不一样。当然,我们现在无需关心头文件顺序了。

  我们为啥要包含头文件呢?头文件里面有定义嘛,使用任何函数之前都必须定义该函数。所以我们并不强求包含头文件,只要你自己在库函数使用之前定义该函数,有些编译器还会自动的添加标准库定义。但是呐,我们还是推荐将头文件添加上去,头文件里面有时候还会包含类型定义、常量定义、宏定义。

  在linux环境下,gcc会在以下路径中查找头文件:/usr/local/include;libdir/gcc/target/version/include;/usr/target/include;/usr/include。C++程序还会查找libdir/../include/c++/version。target是一个标准名指的是你的GCC编译的目录。version则是版本号了。

  Gcc可以使用-Idir参数指定头文件目录。-nostdinc选项则会阻止GCC搜寻某个头文件目录。-nostdinc在编译系统内核的时候会很有用,因为系统内核不使用标准C库,内核使用的是源码里面自带的库文件。注意:-nostdinc对-Idir无效

  我们可以在GCC -I选项参数的任意位置放置-I-标志,在-I-标志之前的目录我们只查找由引号标记的头文件,-I-标记之后的目录则查找所有头文件。你要是想指定查找由引号标记的头文件目录,我们不推荐使用-I-标记,而是使用用-iquote选项。

  如果很不幸,你有一个目录叫"-"。这种情况下你得使用-I./- 和-I-区别开来。

为了防止头文件被包含多次,你需要使用宏的条件语句:

/*File foo. */
#ifndef FILE_FOO_SEEN
#define FILE_FOO_SEEN /*
*the entire file
*/ #endif /*!FILE_FOO_SEEN*/

这是一种很常见的结构被称为wrapper #ifndef

  针对C++的优化:C++会记住wrapper #ifndef的布尔状态,如果第二次重复包含同一个头文件,C++会直接忽略该文件(直接不扫描)。wrapper #ifndef之外的注释并不会影响这种优化。

  一般在系统头文件中像FILE_FOO_SEEN这种宏名以“__”开头,所以在个人头文件中建议使用“_”开头,以防冲突。

  C++中我们有两种方式防止头文件被重复包含,但我们都不推荐使用。

  一、#import

  #import实际上来自于Objective-C的标准做法,是#include的一个变种。#import包含头文件,但最多只包含一次。我们不推荐的理由是:#import放权给了用户,用户必须知道一个头文件必须只包含一次。但我们的宗旨是把这一任务交给头文件来完成。

  二、#pragma once

  #pragma once 指令使用在头文件里面,符合我们的宗旨。但是并不是所有的预处理器都能识别该指令。如果考虑可移植性,该指令显然是要移除的。

  在预处理过程中,预处理器会告诉编译器标记符号的位置,实际上就是哪个文件哪一行。编译出错的时候编译器往往会有提示,告诉你错误可能在那个文件哪一行。这是通过语法解析器在解析代码的时候自动插入的$line 宏

  在glibc中有的函数可能只是一个宏定义,也可能是一个实实在在的函数。这对我们的程序没什么影响。使用宏定义函数的理由是:可以产生内联扩展,这要比函数调用快的多,缺点是不易于debug(原因是编译器给出的行号不是宏展开的地方,而是宏定义的地方)。基于宏定义函数的缺点,你可能想避免使用宏定义函数。你有两种方式来避免:

1、给函数名添加括号

2、使用#undef预处理指令

比如abs函数,既有宏定义也有函数实现。

#include <stdlib.h>
abs(i); //根据编译器选择可能是宏,也可能是函数调用
(abs)(i); //一定是函数调用 #undef abs
abs(i); //一定是函数调用

最新文章

  1. php常用函数
  2. Laravel框架 mysql 数据库 —— 基本使用
  3. 静态代码审查工具FxCop插件开发(c#)
  4. httpserver
  5. Unity逻辑热更新
  6. poj 1664
  7. sdp内容解析
  8. BZOJ 1821 部落划分
  9. C#语法糖之开篇
  10. hbase 0.96 单机伪分布式配置文件及遇到的问题 find命令
  11. 【转】处理新版Chrome书签、菜单字体不清晰
  12. 洛谷 1503 鬼子进村 (set)
  13. Ubuntu环境下的Redis 配置与C++使用入门
  14. canvas图表(1) - 柱状图
  15. 使用&amp;lt;jsp:include&amp;gt;,不想写死URL,动态生成URL的解决的方法
  16. 什么是Docker,它可干什么?
  17. temporal credit assignment in reinforcement learning 【强化学习 经典论文】
  18. Git服务器配置和基本使用
  19. noip第19课资料
  20. 关于ThinkPHP执行长时间任务可能导致PHP使用内存越来越大的问题

热门文章

  1. oracle 之 COMMENT 分类: H2_ORACLE 2014-04-24 15:30 386人阅读 评论(0) 收藏
  2. [Win 8/WP 8]简单实现弹出页更换头像的功能
  3. linux 登录windows跳板机
  4. C++常用数据结构的实现
  5. C#-numericUpDown-数字选择---ShinePans
  6. 新技能 get —— Python 断点续传下载文件
  7. 编写Linux中sh文件执行时出现莫名字符的问题
  8. Linux中特别要注意用户与文件权限的问题
  9. Java设计模式菜鸟系列(二十二)中介者模式建模与实现
  10. BZOJ 1084 [SCOI2005]最大子矩阵 - 动态规划