运行时和编译时有什么区别?

时间:2013-04-07 22:11:07

标签: c# compilation runtime compile-time

那么什么是运行时?它是一个执行半编译代码的虚拟机,无法在特定处理器上运行。如果是这样,那么什么是虚拟机?是否是另一种软件可以进一步将半编译代码转换为机器特定代码?那么如果我们谈论的那些语言之一不能编译成中间代码而是直接翻译/编译成机器代码呢?在那种情况下,运行时是什么时候?是硬件(CPU和RAM)?

另外,编译时和运行时有什么区别?它们是软件生命周期的阶段。我的意思是一个程序最初是一堆文本文件,对吧?因此,您可以将这些数据编译或转换为一种数据形式,然后将其加载到内存并由处理器执行,或者如果它是“托管”语言,那么在它可以在硬件上运行之前需要进一步编译。 什么是托管语言?

最后,是否存在调试时间和它是什么?

我是第一个学习计算机科学的学期,它真的让我感到困惑的是教学的不合逻辑。 “信息”正在被我的喉咙推开,但每当我试图通过将所有相关内容组织成一个明确定义的组件和关系的单一系统来理解所有内容时,我就会陷入困境。

提前致谢, 盖瑞特

3 个答案:

答案 0 :(得分:12)

适合人类推理的代码(让我们称之为“源代码”)需要经过几个翻译阶段才能被底层硬件(如CPU或GPU)物理执行:

  1. 源代码。
  2. [可选]中间代码(例如.NET MSIL或Java字节码)。
  3. 符合目标instruction set architecture
  4. 的机器代码
  5. 实际上翻转硅中逻辑门的微码。
  6. 这些翻译可以在程序的“生命周期”的各个阶段完成。例如,当开发人员“构建”时,特定的编程语言或工具可能会选择从 1 转换为 2 “当用户”运行“它时,程序并从 2 转换为 3 (通常由一个名为“虚拟机” 1 的软件需要预先安装在用户的计算机上。这种情况对于“托管”语言(如C#和Java)来说是典型的。

    或者它可以在构建时直接从 1 转换为 3 ,这对于“native”来说很常见语言如C和C ++。

    3 4 之间的转换几乎总是由底层硬件完成。它在技术上是“运行时”的一部分,但通常被抽象出来,并且对开发人员来说基本上是不可见的。

    术语“编译时间”通常表示从 1 转换为 2 (或 3 )。在程序实际运行之前,可以在编译时执行某些检查,例如确保传递给方法的参数类型与声明的方法参数类型匹配(假设语言是“强类型”)。捕获错误越早,修复就越容易,但这必须与灵活性相平衡,这就是为什么某些“脚本”语言缺乏全面的编译时检查。

    术语“运行时”通常表示从 2 (或 3 )的翻译直到 4 。甚至可以在运行时直接从 1 进行翻译,就像所谓的“解释语言”一样。

    在编译时无法捕获某些类型的问题,您必须使用适当的调试技术(例如调试器,日志记录,分析器等...)在运行时识别它们。运行时错误的典型示例是当您尝试访问不存在的集合的元素时,该元素可能在运行时作为异常显示,并且是执行流程对编译器而言过于复杂的结果在编译时“预测”。

    “调试时间”只是一个运行时,而调试器附加到正在运行的程序(或者您正在监视调试日志等)。


    1 请勿将此与旨在运行本机代码的虚拟机混淆,例如VMware或Oracle VirtualBox。

答案 1 :(得分:4)

编译时和运行时通常指的是何时发生检查或何时发生错误。例如,在像C#这样的静态类型语言中,静态类型检查是在编译时进行的。这意味着如果您尝试将字符串分配给int变量,则无法编译应用程序。另一方面,运行时指的是代码实际执行的时间。例如,异常总是在运行时抛出。

虚拟机等; C#是一种编译成Common Intermediate Language(CIL或IL)的语言。无论您使用哪种.NET语言(C#和VB.NET都生成IL),结果都是相同的代码。然后,.NET Framework使用Just-in-time compilation在运行时执行此语言。所以,是的,您可以将.NET Framework视为一个虚拟机,它针对目标机器代码运行特殊的子语言。

至于调试时间,我认为没有这样的事情,因为你在调试时仍在运行程序。因此,如果有的话,调试时间将是附加调试器的运行时。但你不会使用这样的术语。

答案 2 :(得分:3)

编译时 - 编译器尝试编译某些代码的时间段。示例:“编译器在编译时发现了3个类型错误,导致程序无法编译。”

运行时 - 程序执行的时间段。示例:“我们直到运行时才发现错误,因为它是一个逻辑错误。”

运行时和虚拟机是两个独立的想法 - 你的第一个问题对我没有意义。

虚拟机确实是将“对象”[Java,C#等]代码转换为可在计算机上运行的字节代码的软件程序。如果一种语言使用虚拟机,它也经常使用Just In Time编译 - 这意味着编译时和运行时实际上是在同一时间发生。

相反,C,C ++等编译语言通常在机器上执行之前编译成字节码,因此编译时和运行时完全是分开的。

通常“托管”语言具有垃圾收集(您不直接使用分配和取消分配来操作内存[Java和C#都是示例])并在某种类型的虚拟机上运行。