问题:ide是分离式编译的吗?也就是说,他是只会编译带main函数的那个.cpp还是说会编译所有的.cpp?
答: 编译所有的.cpp。
问: 我感觉他只是编译了带main函数的那个.cpp 了呀,因为我把所有的要用到的.h文件都包含进来了呀!
答: 是的,你把所有的.h文件都包含进来了,但是你也仅仅是把.h文件包含进来了,这个动作仅仅是将.h的内容粘贴过来,而粘贴过来的内容,可能仅仅是一些声明,并没有具体实现代码。那么为什么仅仅有声明,就可以生成最终可执行代码了呢?就是因为他编译了所有其他的.cpp呀!
问: 既然会编译所有的.cpp ,那么为什么需要.h文件呢?
答:是的,本来就不需要。.h文件只是为了更方便的生成.cpp。因为.cpp文件中可能会使用一些东西,例如变量和函数,而这些东西除非是内部创建,否则一定要先声明的,那么声明在哪里声明?可不可以来一个统一的声明?于是就有了头文件。所以说头文件的大多数用处,就是声明。而声明只是使得我们的代码能够通过编译,要想生成可执行代码,还得通过连接才行,而连接的对象是什么?当然是由.cpp文件生成的可执行代码。
所以当我们的项目中有很多.cpp和.h的时候,我们点击构建的时候,其实是包括了编译和连接两个过程,而这其中的编译,是编译所有的.cpp文件,.h文件只是为了方便生成.cpp文件的。另一方面,在连接的时候,是以main函数所在的文件为 主体来连接的,但是这并不意味着我们的main函数代码需要包含其他所有的.cpp,而是只要包含所有用到的代码的声明即可,因为链接器可以通过声明来找到定义。
总之:编译是编译每一个.cpp文件,链接是以main函数所在代码为主线进行连接的。
再次总而言之:编译的对象是.cpp, 连接的对象也是.cpp。
程序员(或者ide)指定编译每一个.cpp文件,而链接器负责将找到main函数中每一个符号的最终实现代码。
.h文件和.cpp文件
首先要知道的是两种文件的最大区别:
编译器将所有.cpp文件编译为.obj文件再串联起来。如果.cpp中有#include
X.h文件,那么第一步预处理会把X.h代码粘贴到.cpp中代替#include语句。基于这个特性,显然,如果我们include
同一工程下的.cpp文件,那么会将该.cpp文件重复两次(一次是本身的编译,一次是include的复制)。因此,.cpp文件不适合进行include。而我们往往需要在一个.cpp文件中include很多其他文件的代码,那么这时候就需要.h文件。
一个比喻就是.h是目录,.cpp是内容。
这里需要再说一下编译的过程,关键是声明和定义的区分。
如果是声明的话,比如声明了一个函数,在汇编语言中就会通过call语句等在全局中寻找这个函数,只需要这个函数在别的.cpp文件中有定义就可以了,而不需要当时就定义。
对变量也是这样,当想使用一个别处定义的变量时,首先要声明,使得该名字为程序所知。
如果不加“extern”的声明,如
int j;
则会自动将j定义为j=0,自动初始化。那么这时就会出现重复定义等错误问题。
因此,应该使用
extern int j;
这将告知程序 有这样一个j存在,就可以使用了。而j的定义在其他.cpp中,整体编译完后就可以获得j的定义了。
函数则会自动默认为是extern的效果。
因此,在.h中进行声明,在.cpp中进行定义。可以避免重复的编译,也更便于管理。
注意,不能在函数体内初始化一个extern变量,因为函数体的作用域仅在函数内。 ————————————————
版权声明:本文为CSDN博主「立花道雪0509」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zanbaixi2128/article/details/81255174