有一回对我说道,“你读过书么?”我略略点一点头。他说,“读过书,……我便考你一考。C++的include,怎样写的?”
在我们一开始接触标准C++的时候,一定都写过这么一段话:
#include <iostream>using namespace std;
但是有时候啊,我们又看到
#include <iostream.h>//这里是VC++ 6.0方言版本写法
那么为什么会有这样的方言呢,include到底是怎么写呢,此文就来大概说道说道。为了探寻上古VC++6.0的方言是这么造成的,我们探访到了MSDN上古时期的页面,https://msdn.microsoft.com/en-us/library/aa229433(v=VS.60).aspx
这里的解释以此为参考。首先,现代标准的两句话,到底说了什么呢。
#include <iostream>
引入了一个叫输入输出流的东西,而在C++标准程序库中,所有的标识符都被定义于一个叫std的namespace中,所以,我们才会写出第二行:
using namespace std;
以此引用标准库std,
而翻阅了大量上古资料之后,我们发现了VC++ 6.0的一些奇特之处。简单的说,在VC++ 6.0中,iostream这样的东西有两套。
首先#include<iostream.h>是方言写法没错,此外另一点就是,#include<iostream>+using和#include<iostram.h>并不是同一种功能的两种表达方式,而是两种不同的东西。方言写法中,并非引入整个命名空间,而是引入一个具体的、6.0特有的库文件。
现代标准的#include到底应该怎么写呢?
我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些写法应该记着。将来做程序的时候,写C++要用。”我暗想我和程序员的等级还很远呢,而且程序员也从亲自写Include,只是从Github上抄抄罢;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是井号include加头文件么?”孔乙己显出极高兴的样子,将两个指头的长指甲敲着键盘,点头说,“对呀对呀!……include有两样写法,你知道么?”我愈不耐烦了,努着嘴走远。
那么说了这么多之后,问题来了,现代标准的#include到底应该怎么写呢?
它有两种写法:
#include <>
#include “”
其中,#include <>的写法,它会指示预处理程序到预定义的缺省路径下寻找文件。而预定义的缺省路径通常是在INCLUDE环境变量中指定的。
如果使用这种写法,编译程序会首先到环境变量的路径下寻找文件,如果没有找到,会到当前目录下继续寻找。
而使用双引号#include “file” 的写法,这种方法会指示预处理其先到当前目录下寻找文件,再到预定义的缺省路径下寻找文件。
好了,这个简答的问题理解了之后,下面我扩展一下,这部分用红色写的部分,算作是一些知识扩展,不一定非要掌握了。
比如说,当前目录下有个文件叫“hello.h”,当前目录下有个子目录叫“dir1”,,在dir1中有也有一个hello.h,还有一个main.c
如果说在main.c文件中,#include “hdr.h”,那么在当前目录下编译”dir1/main.c”,它包含的应该是哪个hello.h呢。
正确答案是“dir1/hello.h”,在gcc和msvc中,include””的写法说代表的“在当前目录寻找”,其实是指在使用了include的源文件的所在目录寻找,而不是编译器的当前工作目录。
实际上这种逻辑,并不在C99的规范之中,而是一种约定俗成的行业规范,
想明白这个问题之后,我们来看看下一个问题,有时候我们会看到#include <string.h> 而有时候我们会看到#include <string>,它们之间又是什么区别呢?
include后面什么时候加.h?加不加.h有什么区别?
以string.h为例,简单的一句话解释是:
string.h是C语言的头文件,包含C语言字符串处理函数,
string 是C++头文件,包含C++字符串class。
.h是C语言的习惯,标准C++库中所有头文件都是不加.h的
这里我们引用一段《effective C++》的话,
暂无评论