关于此,有很多矛盾的信息。虽然有人说C#被编译(因为它被编译成IL然后在运行时被编译为本机代码),但是其他人说它被解释为它需要.NET。 EN Wiki说:
许多解释语言首先被编译为某种形式的虚拟语言 机器代码,然后在运行时解释或编译 到本机代码。
所以我很困惑。有人能解释清楚吗?
答案 0 :(得分:61)
C#编译器将C#编译成IL。
然后,根据需要将此IL实时编译(JIT)到主机的本机汇编语言中。但是,可以编写一个解释IL的.NET运行时。即使这样做了,我仍然认为c#是一种编译语言。
答案 1 :(得分:33)
纯编译语言有一些优点。速度通常和工作集大小一样。 纯粹的解释语言有一些优点。不需要显式编译阶段的灵活性,允许我们进行适当的编辑,并且通常更容易移植。
在这种情况下,jitted语言适合中间地带。
这就是为什么我们可能会认为根据我们关心到达哪个指标的位置,以及我们对一个或另一个的偏见而对编译或解释的j语言进行解释。
C#也可以在第一次运行时编译,就像在ASP.NET中一样,这使得它在这种情况下接近解释(虽然它仍然编译为IL,然后在这种情况下进行jitted)。当然,它具有在这种情况下解释的所有优点(与经典ASP中使用的VBScript或JScript相比),以及编译的许多优点。
严格来说,没有任何语言可以使用语言进行搜索,解释或编译。我们可以将C#转换为本机代码(尽管如果它像动态加载程序集那样仍然会使用IL和jitting)。我们可以为C或C ++编写一个内部版本(有几个人已经这样做了)。在最常见的用例中,C#被编译为IL,然后进行jitted,这不是解释的经典定义,也不是编译的。
答案 2 :(得分:14)
基于观点的语义和陈述太多。
首先:C#不是解释性语言; CLR和JVM被认为是"运行时"或者"中间件",但同样的名称适用于像Perl这样的东西。这使得与名字有关的人产生了很多困惑。
术语"口译员"引用运行时通常意味着现有代码解释一些非本机代码。有两种大范例:解析读取原始源代码并采取逻辑操作;字节码执行首先将代码编译为非本机二进制表示,这需要更少的CPU周期来解释。
Java最初编译为字节码,然后通过解释器;现在,JVM读取字节码并及时将其编译为本机代码。 CIL也是这样做的:CLR使用即时编译到本机代码。
考虑运行源代码,运行字节码,编译到本机,即时编译,通过编译器运行源代码到实时原生的所有组合,等等。语言是否被编译或解释的语义变得毫无意义。
作为示例:许多解释语言使用即时字节码编译。 C#编译为CIL,JIT编译为本机;相比之下,Perl立即将脚本编译为字节码,然后通过解释器运行此字节码。您只能以CIL字节码格式运行C#程序集;您只能以原始源代码格式运行Perl脚本。
即时编译器还运行许多外部和内部仪器。运行时跟踪各种函数的执行,然后调整代码布局以优化其特定执行流的分支和代码组织。这意味着JIT代码可以比本机编译的代码运行得更快(例如C ++,或者像C#通过IL2CPP运行),因为JIT在运行时将其优化策略调整为代码的实际执行情况。
欢迎来到计算机编程世界。我们决定使它非常复杂,然后将非描述性名称附加到所有内容上。其目的是为没有实际意义的词语定义创造火焰。
答案 3 :(得分:11)
请看这里:http://msdn.microsoft.com/library/z1zx9t92
用C#编写的源代码被编译成中间语言 (IL)符合CLI规范。
(...)
执行C#程序时,程序集被加载到CLR中, 可能会根据中的信息采取各种行动 表现。然后,如果满足安全要求,则CLR执行 及时(JIT)编译将IL代码转换为本机代码 机器说明。
答案 4 :(得分:10)
如果您感觉,学习或者是老上学,那么编译的EXE将从源代码转换为机器代码,然后解释C#。 如果您认为编译意味着将源代码转换为其他代码(如字节代码),则转换为是。对我来说,解释了任何需要运行时处理才能在其构建的操作系统中工作的东西。
答案 5 :(得分:4)
首先让我们理解解释和编译的定义。
"Compile" (when referring to code)表示将代码从一种语言翻译成另一种语言。通常从人类可读的源代码到目标处理器可以...处理的机器代码。
"Interpret" (when referring to code) ALSO意味着将代码从一种语言翻译成另一种语言。但这次它通常用于从人类可读的源代码转换为由虚拟机获取的中间代码,该虚拟机将其解释为机器代码。
只是要清楚了
源代码 - >编译器 - >机器代码
源代码 - >编译器 - >字节代码 - >口译员 - >机器代码
理论上,任何语言都可以是interpreted或compiled。通常,Java被编译为字节码,由Java虚拟机将其解释为机器码。 C#通常被解释为字节码,由CLR(公共语言运行库,另一个虚拟机)编译。
到目前为止,整个事情都是营销噱头。添加了“解释”一词(或者至少增加了使用量)以帮助展示整洁just-in-time compiling的含义。但他们本可以使用“编译”。区别在于更多的是对英语和商业趋势的研究,而不是任何技术性的研究。
答案 6 :(得分:2)
C#在其生命周期内 解释和编译。 C#被编译为虚拟语言,由VM解释。
混淆源于“编译语言”的模糊概念。
从某种意义上说,“编译语言”是用词不当,因为编译或解释不是语言的属性,而是运行时的属性。e.g。您可以编写一个C解释器,但人们通常将其称为“编译语言”,因为C实现编译为机器代码,并且该语言的设计考虑了编译。
答案 7 :(得分:2)
大多数语言(如果不是全部的话)都需要一个解释器,以将其脚本翻译成机器代码,以使cpu理解并执行它!
每种语言对翻译过程的处理方式都不一样!
例如,“ AutoIt”就是我们可以描述为100%解释的语言!
为什么?
因为执行脚本时始终需要“ AutoIt”解释器!请参见下面的示例:
Loop, 1000
Any-Code
“ AutoIt”解释程序必须将“ Any-Code”转换为机器代码1000次,这会自动使“ AutoIt”成为慢速语言!
另一方面,C#处理翻译过程的方式不同,在脚本执行之前,C#的解释器仅需要一次,之后在脚本执行期间不再需要!
C#的解释器只需将“ Any-Code”翻译为一次机器代码,即可自动使“ C#”成为一种快速的语言!
基本上,
在脚本执行过程中需要其解释程序的语言是“解释语言”!
只需要一次解释器(在脚本执行之前)的语言就是“编译语言”!
最后,
“ AutoIt”是一种“解释语言”!
“ C#”是一种“编译语言”!
答案 8 :(得分:1)
我认为这是一个非常古老的话题。
从我的观点来看,解释后的代码将通过一个解释器,逐行翻译并同时执行。就像示例javascript一样,它是一个解释代码,当一行javascript遇到错误时,脚本就会破坏。
在编译代码时,它将通过编译器,一次将所有代码转换为另一种形式的代码,而不首先执行它。执行是在另一个环境中。
答案 9 :(得分:0)
C#是可编辑的语言。
可能,我重复一遍,可能是因为我遇到了那种意见,有人认为有一个C#语言的翻译,这是因为像
这样的项目。或者,例如,着名的
在这里你可以只编写代码行并执行它们,这会让人想到它 Python喜欢语言,不正确。它编译这些行并执行它们,就像普通的可编译编程语言一样(从工作流的角度来看)。
答案 10 :(得分:0)
答案 11 :(得分:0)
由于计算机只能执行二进制代码,因此任何语言都会导致二进制代码的产生。 问题是:语言是否允许您以二进制代码生成程序? 如果是,那么它是一种编译语言:根据定义,“编译”语言中的“编译”是指编译成二进制代码,而不是转换成某些中间代码。 如果该语言导致为程序生成这样的中间代码,则需要一个额外的软件来执行该代码的二进制编译:它是一种解释语言。 C#程序是否可以直接在机器上“编译”而不需要在这台机器上安装任何其他软件?如果不是,则它是一种解释性语言。 对于解释语言,它是一个解释器,它将生成基础二进制代码,大部分时间是以动态方式生成的,因为这种机制是这些语言灵活性的基础。 REM。 :有时它看起来并不明显,因为解释器捆绑在操作系统中
答案 12 :(得分:0)
如果我们同意解释器的定义«在计算机科学中,解释器是一种计算机程序,它直接执行,即执行用编程或脚本语言编写的指令,而不需要先将它们编译成机器语言程序。»毫无疑问:C#不是解释性语言。