深入学习C++——5C++工作原理

分析main.cpp

对于一个后缀为.cpp的C++源文件,先来分析一下文件的结构

#符号之后的都是预处理语句(叫预处理的原因为它实际上在编译之前就发生了)。#include的含义是找到<>中的文件,然后将该文件中的所有内容拷贝到现在的文件内。这些被包含的文件称为头文件,在C++中通常以.hpp为后缀。

来看一个预处理的神奇操作

1
2
3
4
5
6
7
/*file2.hpp*/
}
/*file1.cpp*/
int main()
{
return 0;
#include "file2.hpp"

这个程序能否成功编译?可以看到main函数是没有右花括号的,但是#include "file2.hpp"这一句将file2中的文件原封不动拷贝到了当前的地方,即补上了一个花括号,所以可以编译成功。

除了#include,常用的预处理命令还有#if #endif,这一对是这么用的:

1
2
3
4
5
6
7
8
9
//int a = 1;会被编译
#if 1
int a = 1;
#endif

//int a = 1;不会被编译
#if 0
int a = 1;
#endif

接下来是main函数。main函数是程序的入口,当运行程序时计算机从这个函数开始执行代码。在这里,main函数的返回类型是int,但是代码中没有返回任何东西,这是因为main函数是特殊的,它不一定需要返回值。没有写return进行返回的话,它会默认返回了0。注意,这只对main函数适用!

<< 符号叫做重载运算符,可以理解为一个函数。

代码如何编译为二进制文件

项目中的每一个cpp文件都会被编译,但是头文件不会被编译,头文件的内容在预处理时全部拷贝到了到了cpp中。每一个cpp文件都被编译为object file(目标文件),我们需要将这些文件合并成一个执行文件,链接(Link)会将所有的目标文件合并成一个.exe文件。

如果在一个文件(比如main.cpp)中使用了另一个文件中的函数,编译会报错,需要在main.cpp中声明那个函数的存在。声明表示这个符号、函数是存在的,去掉函数的结构体后加分号就是函数的声明。声明与定义不同,定义是说明这个函数到底是什么,是函数的函数体。void Log(const char* message);这就是一个声明,其实void Log(const char*);这样写也可以,但习惯上使用前者,会更加清晰。在构建整个项目时,所有.cpp文件都会被编译,链接器会找到正确的Log函数的定义在哪里,如果找不到定义,会报链接错误。

关于编译器和链接器会单独讲解


文章作者: 范子琦

文章链接: https://www.fanziqi.site/categories/C/

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 范子琦的博客