一个可执行程序通常有几个.cpp、.h文件,那么这些文件在编译时是怎么连接的,譬如我在1.cpp定义一个int a,在2.cpp中引用了它,编译器是怎么找到a的定义的?另外,一个可执行程序要用到很多MFC类,这些类定义在不同的文件中,编译器是怎么找到它们的?
改回答引用ChatGPT
C++ 程序通常由多个源文件(.cpp)和头文件(.h)组成,在编译时需要进行预处理、编译、汇编、链接四个步骤。
在编译时,编译器将每个 .cpp 文件编译成一个目标文件(.o),该文件存储了程序代码的机器语言代码和符号表(包括变量、函数等定义)。在链接阶段,编译器将所有的目标文件连接在一起,生成可执行程序。
如果在 1.cpp 中定义了 int a,在 2.cpp 中引用了 a,那么 2.cpp 编译出的目标文件中并不包含 a 的定义,需要在链接阶段通过符号表找到 a 的定义。这就是为什么需要头文件的原因,头文件用于在编译各个 .cpp 文件时提供公共的定义和声明。
对于 MFC 类,编译器通过预编译的头文件(比如 <afxwin.h>)或者自定义的头文件找到类的定义,然后在编译目标文件时使用这些定义。在链接阶段,连接器会找到 MFC 类的实现,把它们加入到可执行程序中。
不知道你这个问题是否已经解决, 如果还没有解决的话:编写好以后就需要编译,这取决于用的操作系统和编译器。而编译器一般都具备集成开发环境(IDE),但是是怎么样进行的?
1.进行预编译:这一步就是把你的头文件都拷贝进你的.cpp里面;把你的#define进行替换;处理条件编译指令,带#的;把注释给删除了;保留#pragma编译器命令,因为编译程序需要。*
*1:由于笔记本容量较小,下载的是VSCode,利用MingW进行编译。搜索得知MingW是把开源C语言编译器gcc移植到windows下。
*2:#pragma Para预处理语句(目前只看到#pragma once,只编译一次头文件):作用是设定编译器的状态,或者完成指定动作。比如说让输出窗口输出消息,或者是什么动作做多少次。
2.编译:高级语言翻译成机器语言,即完成词法分析,语法分析,语义分析然后优化为汇编语言(生成.obj文件)*,再转为二进制。
*:汇编语言是可以对硬件进行操作的,相较于机器语言,有相应英文缩写,更容易记忆。
3.链接:将生成的二进制的文件和包含的库(功能?)链接在一起,进行实现。
如何从.c到实现的过程,参考:
https://www.cnblogs.com/mhq-martin/p/11898245.html$是系统提示符,-o prog1是编译器参数,指定了可执行文件的文件名。在不同的系统中,生成一个prog1 或者prog1.exe的可执行文件。
C:\Users\me\Programs> cl/EHsc prog1.cpp。
C:\Users\me\Programs>指的是你的目录,你现在在哪儿操作。cl是运行编译器命令。/EHsc是编译器选项,用来打开标准异常处理。
*:异常:结构化异常和C++异常
结构化异常:指的是整数/0,访问无效地址 常见代码
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_STACK_OVERFLOW,EXCEPTION_INT_DIVIDE_BY_ZERO
C++异常:又称同步异常,一般是调用API导致
*:/EHsc (EH exception handling异常处理)是 /EHs 和/EHc 的结合
/EHa可以捕捉异常,让后面的东西继续运行,完成局部函数的析构,但是其他不可。但是假设不发生异常(?)太多了,后面专门学习。
关于异常处理命令
**