C/C++的编译过程中到底发生了什么?
2017-01-23 17:22
423 查看
/刚回到家就生病了,原来自己的房间被老妈当成了书房,被赶到了餐厅,旁边电视里还放着京剧,一边听京剧一边写博客,醉了。。。 /
标题党,其实我也不知道发生了啥。只是看了一点相关的文章,自己简单总结下编译过程中容易搞混的概念:
从.c文件到.exe文件大概经历了这三个阶段:
f.cpp(C++语言编写的源代码文件)–预处理—> f’.cpp(C++语言编写的源代码文件)—编译—>f.obj(目标文件)—连接—>f.exe(可执行文件)
首先,在预处理阶段,主要包括宏定义、文件包含、条件编译三种情况。宏定义如#define s(a,b) (a)*(b) 注意是直接的文字替换,要加括号,s (a,b)中间没有空格。宏定义可以嵌套不能递归。文件包含即#include 头文件,头文件可以预编译以减少开销。比如写一个只包含#include “preh.h”的.c文件(通常记作预编译头文件pch),在编译器中指定create compiled header file,其余include该头文件的.c文件中,设置 use precompiled header即可。(如果哪天看到了一个只包含.h的.c文件,不要马上删掉它。。。)条件编译通常是用#ifdef/ifndef… #define..#endif这种形式,这样的可以通用。也有#pragma para 这样的,比如用#pragma once 来使该文件只编译一次,但pragma命令不可移植,不同的编译器可能会以不同的方式来解释同一pragma命令。
然后,在编译阶段,会将C/C++语言转变为纯汇编语言(会做包括词法分析、语法分析、语义分析的工作,有error就compiled failed),再变为与CPU相关的二进制码,即机器指令。
最后,根据makefile来link生成的目标文件(.object/.o)。这里可以和预处理的文件包含结合起来看。比如,b.cpp中inlcude了a.h,c.cpp中又引用了b.cpp的函数fun。那么通常,连接器会在项目/地址下的每一个目标文件中找这个fun, 会统统搜一遍,找到了也会继续搜完,然后再build到对应的exe中。所以要避免重复定义函数名,不然就会爆错refined,生成exe 失败。一般linux系统需要自己写makefile,vc之类的ide则会自动生成。
就这些,再有问题多google。
参考文章:这个讲的最细致,.c和.h文件的区别
http://www.51hei.com/bbs/dpj-27169-1.html
http://blog.csdn.net/z1179675084/article/details/8426130 这个比较清晰,说了几组概念
其余的,百度文库或者csdn上一搜一把,多看几篇就差不多有个底了。也许应该看看《编译原理》的视频教程也有帮助。最后推荐那个C语言他爹写的书,貌似是《THE C PROGRAMMING LANGUAGE》,虽然有点老,内容也不多,但很透彻。
标题党,其实我也不知道发生了啥。只是看了一点相关的文章,自己简单总结下编译过程中容易搞混的概念:
从.c文件到.exe文件大概经历了这三个阶段:
f.cpp(C++语言编写的源代码文件)–预处理—> f’.cpp(C++语言编写的源代码文件)—编译—>f.obj(目标文件)—连接—>f.exe(可执行文件)
首先,在预处理阶段,主要包括宏定义、文件包含、条件编译三种情况。宏定义如#define s(a,b) (a)*(b) 注意是直接的文字替换,要加括号,s (a,b)中间没有空格。宏定义可以嵌套不能递归。文件包含即#include 头文件,头文件可以预编译以减少开销。比如写一个只包含#include “preh.h”的.c文件(通常记作预编译头文件pch),在编译器中指定create compiled header file,其余include该头文件的.c文件中,设置 use precompiled header即可。(如果哪天看到了一个只包含.h的.c文件,不要马上删掉它。。。)条件编译通常是用#ifdef/ifndef… #define..#endif这种形式,这样的可以通用。也有#pragma para 这样的,比如用#pragma once 来使该文件只编译一次,但pragma命令不可移植,不同的编译器可能会以不同的方式来解释同一pragma命令。
然后,在编译阶段,会将C/C++语言转变为纯汇编语言(会做包括词法分析、语法分析、语义分析的工作,有error就compiled failed),再变为与CPU相关的二进制码,即机器指令。
最后,根据makefile来link生成的目标文件(.object/.o)。这里可以和预处理的文件包含结合起来看。比如,b.cpp中inlcude了a.h,c.cpp中又引用了b.cpp的函数fun。那么通常,连接器会在项目/地址下的每一个目标文件中找这个fun, 会统统搜一遍,找到了也会继续搜完,然后再build到对应的exe中。所以要避免重复定义函数名,不然就会爆错refined,生成exe 失败。一般linux系统需要自己写makefile,vc之类的ide则会自动生成。
就这些,再有问题多google。
参考文章:这个讲的最细致,.c和.h文件的区别
http://www.51hei.com/bbs/dpj-27169-1.html
http://blog.csdn.net/z1179675084/article/details/8426130 这个比较清晰,说了几组概念
其余的,百度文库或者csdn上一搜一把,多看几篇就差不多有个底了。也许应该看看《编译原理》的视频教程也有帮助。最后推荐那个C语言他爹写的书,貌似是《THE C PROGRAMMING LANGUAGE》,虽然有点老,内容也不多,但很透彻。
相关文章推荐
- 编译到底做了什么(***.c -> ***.o的过程)
- 网页打开过程到底发生了什么
- C++中include头文件到底会发生什么事?
- 字符串从内存写入到磁盘的过程中到底发生了什么(一)
- Qt for Visual C++ 编译过程
- C++编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决
- c,c++,vc++,c++buider到底有什么区别和联系
- c,c++,vc++,c++buider到底有什么区别和联系
- 低格过程到底对硬盘进行了什么操作?
- 大家编译c/c++都用什么编译器呀?
- c++模板类(一)理解编译器的编译模板过程
- [讨论]过程与流程到底有什么区别?
- 受力的物体内部到底发生了什么情况—解释惯性力学三定律
- 【转】C++编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决
- 不同种类的整型比较,到底发生了什么?
- ResultSet.TYPE_SCROLL_SENSITIVE到底发生了什么?
- c,c++,vc++,c++buider到底有什么区别和联系
- [VC++入门]搞了半天我终于知道C++那种头文件h和源文件cpp到底在搞什么
- c,c++,vc++,c++buider到底有什么区别和联系
- java编译过程与c/c++编译过程不同