C++是如何工作的

1、编译和链接

编译器对每一个源文件进行编译,生成对应的obj文件
链接器将它们进行合并,生成一个exe文件

1、#符号之后的都是预处理语句,编译器收到源文件之后先处理这个预处理语句。它叫预处理的原因就是,在编译之前就被处理了。比如#include语句,就是找到iostream文件,然后将它的所有内容拷贝到现在的文件内。

2、如何将源文件转换为可运行的二进制文件:编译器先预处理, 然后进行编译,生成object文件,后缀是.obj,然后用连接器将这些.obj文件合并成一个可执行文件即.exe文件。

3、debug比release慢是因为很多优化被关掉了,关掉优化的好处是让我们可以调试代码。

4、项目里的所有cpp文件都会被编译,但头文件不会被编译,仅会编译cpp文件,因为在预处理的时候,头文件的内容已经被复制进来了。

5、如std::cout << “hello world” << std::endl;如果我不想使用cout进行打印,可以再写一个函数:

//main.cpp
void Log(const char* message)
{
	std::cout << message << std::endl;
}

int main()
{
	Log("hello world");
}

但我不喜欢把很多函数都包含在main.cpp文件中,我希望把代码分到很多文件当中,这样可以保证文件的干净整洁。 所以我们创建一个log.cpp文件,再里面写Log函数,在main.cpp里进行调用:

//log.cpp
#include<iostream>
void Log(const char* message)
{
	std::cout << message << std::endl;
}
//main.cpp
int main()
{
	Log("hello world");
}

发现报错,一个问题是main没有包含iostream头文件,另一个是找不到Log文件,因为main()函数不知道Log函数,我们可以通过声明Log函数来修复问题:

//log.cpp
#include<iostream>
void Log(const char* message)
{
	std::cout << message << std::endl;
}
//main.cpp
#include<iostream>
//声明Log函数
void Log()(const char* message);

int main()
{
	Log("hello world");
}

声明就像告诉编译器,Log函数是存在的,编译器会相信,而且它不关心Log函数是否真存在,在哪里定义,它不管,因为这是链接器的工作,如果把log.cpp中的Log函数名改为Logr,点击编译兵没有报错,但点击运行,就会出现链接错误。因为编译器不管函数的定义,链接器会在源文件中寻找Log函数的定义,他的工作是连接函数,当它发现没有Log函数的定义,则出现报错。

2、编译器是如何工作的

总的来说,编译器可以将文本文件转换成目标文件 .obj,obj可以传递到连接器,目前先讨论编译器。

编译器在生成obj时,实际上做了几件事:

  1. 预处理我们的代码,即先处理所有的【预处理语句】,即#include、#define、#if、#endif语句等
  2. 再进行编译,即词法分析、语法分析、语义分析等,确定所有语句都合法后,将它们翻译成中间文件.s
  3. 然后进行汇编,将中间文件翻译成目标机器指令.o

2、链接器

将所有.obj文件链接成.exe文件,.exe文件为全局可见文件

链接步骤:

  1. 合并段、符号表
  2. 符号解析:在符号引用地找到符号定义地
  3. 分配地址空间
  4. 符号重定位

静态链接和动态链接:
1、静态链接,在链接阶段,把需要的所有函数二进制代码包含到可执行文件中去,完成所有符号引用的一种链接方式。

2、动态链接,在链接的时候不直接拷贝相应依赖库的代码,而是记录一系列的符号和参数,才程序运行或加载时,将这些信息传递给操作系统,操作系统将需要的依赖库加载到内存中。

区别:
静态链接比动态链接要快
动态链接比静态链接省内存

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值