我试图了解这些语言是如何工作的。不幸的是,我只读过非常肤浅的东西。 我将总结我已经知道的内容,如果你能纠正我,我会非常高兴,最重要的是,帮助我提高我的一点半知识。
C ++:
C ++编译器预处理所有源文件。这意味着它实际上将字符串插入到最初位于宏的位置。之后,它为包含机器独立字节码的每个源文件创建一个.obj文件。 链接器然后将库中的所有外部.obj文件与定制的.obj文件链接在一起,并将其编译为.exe。
爪哇:
Java代码被编译成机器独立的“字节码”,它位于.class文件中,而后者又可以放在JAR上运行的.JAR文件中。虚拟机正在进行垃圾清理。 Java代码就像C#一样及时编译,但是由SUN开发的热点优化。
C#:
几乎和Java一样? C#源代码被编译成CIL(通用中间语言)代码,这仍然是人类可读的。此代码将由CLR Just-in-Time运行。这种编译只是在首次调用时将方法转换为机器特定的代码。
我实际上对几乎所有语言都感兴趣...但Java和C#几乎相同,我总是想知道如何区分。可以说,C ++是“经典”。两个父亲都没有任何虚拟机。感谢帮助!
编辑:我知道这是一个广泛的主题,但我真的找不到任何扎实的知识。如果你有解释这类事情的链接或书籍,我很乐意去上班。我试着阅读java虚拟机的SUN规范/白皮书,但现在这对我来说有点太深了。
答案 0 :(得分:6)
非托管C ++的编译与托管C ++,C#和Java的编译非常不同。
非托管C ++(“传统”C ++)直接编译为机器代码。程序员调用针对特定平台(处理器和操作系统)的编译器,并且编译器输出仅在该平台上有效的可执行文件。可执行文件包含特定处理器可以理解的机器代码。执行时,处理器将按原样直接执行编译的代码(模数虚拟内存地址转换yadda yadda)。
托管代码被编译为中间代码(在C#等.NET语言的情况下为CIL,在Java情况下为Java字节代码)。编译器输出包含此中间语言代码的可执行文件。此时,它仍然是平台无关的。执行时,所谓的 Just-in-Time编译器将启动,在执行之前将中间代码转换为机器代码。然后,处理器将执行JIT编译器生成的机器代码。大多数情况下,这个机器代码保存在内存中并在程序结束时丢弃(因此下次必须再次运行JITting),但是存在永久执行JIT的工具。
这里的好处当然是独立于平台的可执行文件可以在任何平台上运行,但缺点是你需要一个执行环境(包括一个JIT编译器)用于该平台。 / p>
答案 1 :(得分:1)
非常好。
C ++的.obj文件取决于机器,但通常没有解析内存地址。链接器只需获取.obj文件并将它们链接在一起,并将许多地址解析为绝对值。
说虚拟机只是在进行垃圾清理 - 甚至不确定这意味着什么,这是不正确的。 VM读取代码字节并对每个代码进行解码,因此VM就像一个CPU。当它发现一堆重复执行的代码时,它可以用真正高度优化的机器代码替换该字节码 - 即JIT编译。
我认为其余的都是正确的 - 虽然我不能老实说C#的CIL是否具有人类可读性。
答案 2 :(得分:0)
所有三种语言几乎相同(它们都是必需的OO语言),主要区别在于
C ++编译器将更加努力地优化它生成的代码,因为它无法将低级优化的优势传递给JIT编译器。