运行时与编译时间

dev*_*all 340 runtime compile-time

任何人都可以让我很好地理解运行时和编译时的区别是什么?

Nor*_*sey 445

编译时间和运行时间之间的差异是尖头理论家称之为阶段区分的一个例子.这是最难学习的概念之一,特别是对于没有很多编程语言背景的人.为了解决这个问题,我觉得提问很有帮助

  1. 程序满足哪些不变量?
  2. 在这个阶段会出现什么问题?
  3. 如果阶段成功,后置条件是什么(我们知道什么)?
  4. 如果有的话,输入和输出是什么?

编译时间

  1. 该程序不需要满足任何不变量.事实上,它根本不需要是一个结构良好的程序.您可以将此HTML提供给编译器并观察它barf ...
  2. 编译时会出现什么问题:
    • 语法错误
    • Typechecking错误
    • (很少)编译器崩溃
  3. 如果编译器成功,我们知道什么?
    • 该计划形式良好 - 无论用何种语言都是一个有意义的计划.
    • 可以开始运行程序.(该程序可能会立即失败,但至少我们可以尝试.)
  4. 什么是输入和输出?
    • 输入是正在编译的程序,以及为了编译而需要导入的任何头文件,接口,库或其他voodoo .
    • 希望输出汇编代码或可重定位目标代码甚至可执行程序.或者如果出现问题,输出就是一堆错误消息.

运行

  1. 我们对程序的不变量一无所知 - 它们是程序员所放的任何东西.运行时不变量很少由编译器强制执行; 它需要程序员的帮助.
  2. 可能出现的错误是运行时错误:

    • 被零除
    • 取消引用空指针
    • 内存耗尽

    此外,程序本身可能会检测到错误:

    • 试图打开不存在的文件
    • 尝试查找网页并发现指称的网址格式不正确
  3. 如果运行时成功,程序将完成(或继续)而不会崩溃.
  4. 输入和输出完全取决于程序员.文件,屏幕上的窗口,网络数据包,发送到打印机的作业,您的名字.如果程序发射导弹,那就是输出,它只在运行时发生:-)

  • 我是唯一一个已经陷入"不变量"的人吗? (20认同)
  • 它覆盖的内容非常好(+1),但是你甚至没有触及编译时与运行时的元编程方面,恕我直言,这是最有趣的部分.鉴于这个答案已经被接受,我会批准它可能超出OP所寻求的范围. (13认同)
  • 这是非常好的答案.它非常清晰易懂.在Google中找到那么明确的答案并不容易. (12认同)
  • "程序不需要满足任何不变量.实际上,它根本不需要是一个格式良好的程序.你可以将这个HTML提供给编译器并观察它吧..."我不知道你在说什么这里.你能用简单的术语解释一下,不是所有这些技术垃圾都挤满了吗? (9认同)
  • 即使你已经编程了一段时间,它仍然不容易得到......它不仅仅是新手.OP的好问题. (4认同)
  • 很好,如果有人在我的讲座中问我,我会用你的anwser :-) (3认同)
  • "我们对程序的不变量一无所知 - 它们都是程序员所放入的.运行时不变量很少由编译器强制执行;它需要程序员的帮助." 即使在查看Wiki之后,我也不了解不变量 (3认同)
  • @carloswm85 “不变式”可以被认为是对代码的行为和执行的保证。假设您编写一个程序来计算存储在一堆不同文件中的公司费用。根据您的系统,最有效的实现可能有一个不变量,例如“每个文档仅读取一次”。由您决定如何编写执行此操作的代码,并且由于这是运行时行为,因此如果您犯了错误或对程序的不变量撒谎,则没有编译器会发现您。 (3认同)
  • @Pithikos,它开始的很好,听起来像他要丢下顿悟,然后我碰到那部分,就像...哦...另一个堆栈溢出的帖子,那里有人用深奥的答案回答和深奥的问题。大。 (2认同)
  • 哈,这很有趣,几乎有 500 个人对此表示赞同,但 10 年来没有人解释这个神秘的“不变量”……最后 jlau 对此发表了评论,但这里对你们中的一些人有一个更清楚的解释:不变量是一种我们开发人员应该遵循的“规则”,但编译器对此一无所知。感谢:https://softwareengineering.stackexchange.com/a/364286 (2认同)

puf*_*ish 164

我从错误的角度考虑它,何时可以捕获它们.

编译时间:

string my_value = Console.ReadLine();
int i = my_value;
Run Code Online (Sandbox Code Playgroud)

无法为字符串值分配int类型的变量,因此编译器在编译时确定该代码存在问题

运行:

string my_value = Console.ReadLine();
int i = int.Parse(my_value);
Run Code Online (Sandbox Code Playgroud)

这里的结果取决于ReadLine()返回的字符串.有些值可以解析为int,有些则不能.这只能在运行时确定

  • 现在这是我们都能理解的.这里没有一般的垃圾技术词.尼斯. (53认同)
  • 这是一个很好的底线答案,它概念性地涵盖了编译和运行时之间的差异.我很欣赏所选择的学术,教授答案,但这个答案清晰简洁.读完这个答案之后,我可以回过头来阅读所选择的答案,这更有意义.谢谢 (2认同)

Yuv*_*dam 64

编译时:您(开发人员)编译代码的时间段.

运行时间:用户运行您的软件的时间段.

你需要更明确的定义吗?

  • @BCS:OP可能使用解释或字节编译然后运行一步语言对编程进行了非常简单的介绍,因此永远不需要区分.天真的问题,但*不*愚蠢. (11认同)
  • @Robben 我假设你已经得到了这么长时间的答案,但我会为其他人回答。是的,即使你不使用它也会是一个运行时错误 (2认同)

M4N*_*M4N 21

(编辑:以下内容适用于C#和类似的强类型编程语言.我不确定这对你有帮助).

例如,在运行程序之前,编译器将检测到以下错误(在编译时),并将导致编译错误:

int i = "string"; --> error at compile-time
Run Code Online (Sandbox Code Playgroud)

另一方面,编译器无法检测到如下错误.您将在运行时(程序运行时)收到错误/异常.

Hashtable ht = new Hashtable();
ht.Add("key", "string");
// the compiler does not know what is stored in the hashtable
// under the key "key"
int i = (int)ht["key"];  // --> exception at run-time
Run Code Online (Sandbox Code Playgroud)


dmc*_*kee 18

将源代码翻译成[发生在[屏幕|磁盘|网络]上的东西)可以(大致)以两种方式进行; 叫他们编译和解释.

编译的程序中(例子是c和fortran):

  1. 源代码被送入另一个程序(通常称为编译器 - go figure),它产生一个可执行程序(或错误).
  2. 运行可执行文件(通过双击它,或在命令行上键入它的名称)

在第一步中发生的事情据说发生在"编译时",在第二步中发生的事情据说发生在"运行时".

解释程序中(例如MicroSoft basic(在dos上)和python(我认为)):

  1. 源代码被送入另一个程序(通常称为解释器),它直接"运行"它.这里的解释器充当程序和操作系统(或非常简单的计算机中的硬件)之间的中间层.

在这种情况下,编译时间和运行时间之间的差异很难确定,并且与程序员或用户的相关性更低.

Java是一种混合体,其中代码被编译为字节码,然后在虚拟机上运行,​​该虚拟机通常是字节码的解释器.

还有一个中间案例,其中程序被编译为字节码并立即运行(如在awk或perl中).


Spe*_*nce 11

基本上,如果您的编译器可以解决您的意思或"编译时"值是什么,它可以将其硬编码到运行时代码中.显然,如果运行时代码必须在每次运行速度较慢时进行计算,那么如果您可以在编译时确定某些内容,那就更好了.

例如.

恒定折叠:

如果我写:

int i = 2;
i += MY_CONSTANT;
Run Code Online (Sandbox Code Playgroud)

编译器可以在编译时执行此计算,因为它知道2是什么,以及MY_CONSTANT是什么.因此,它不会在每次执行时执行计算.


dic*_*oce 8

嗯,好吧,运行时用于描述程序运行时发生的事情.

编译时用于描述在构建程序时(通常由编译器)发生的事情.


BCS*_*BCS 8

编译时间:

在生成程序时,在编译时完成的事情(几乎)不会产生任何成本,但在构建程序时可能会产生很大的成本.

运行:

或多或少恰恰相反.构建时成本很低,程序运行时成本更高.

从另一边; 如果在编译时完成某些操作,它只在您的计算机上运行,​​如果某些内容是运行时,它将在您的用户计算机上运行.

关联

这很重要的一个例子是单位携带类型.编译时版本(如Boost.Units我在D中的版本)的结果与使用本机浮点代码解决问题的速度一样快,而运行时版本最终不得不打包有关值的单位的信息.并在每次操作中对它们进行检查.另一方面,编译时版本要求在编译时知道值的单位,并且不能处理它们来自运行时输入的情况.


Pan*_*ash 8

以前类似的问题回答以下是运行时错误和编译器错误之间的区别?

编译/编译时间/语法/语义错误:编译或编译时错误是由于输入错误而发生的错误,如果我们不遵循任何编程语言的正确语法和语义,则编译器会抛出编译时错误.在删除所有语法错误或调试编译时错误之前,它们不会让程序执行单行.
示例:在C中缺少分号或错误输入intInt.

运行时错误:运行时错误是程序处于运行状态时生成的错误.这些类型的错误会导致程序出现异常行为,甚至可能导致程序中断.它们通常被称为例外.
示例:假设您正在读取不存在的文件,将导致运行时错误.

阅读更多有关所有编程错误的信息


小智 6

以下是《Java 编程简介》的作者 Daniel Liang 关于编译主题的引用:

“用高级语言编写的程序称为源程序或源代码。由于计算机无法执行源程序,因此必须将源程序翻译机器代码才能执行。翻译可以使用另一种称为解释器或编译器。” (Daniel Liang,“JAVA 编程简介”,第 8 页)。

...他继续...

“编译器将整个源代码翻译成机器代码文件,然后执行机器代码文件”

当我们输入高级/人类可读的代码时,这起初是无用的!它必须在您小小的 CPU 中转化为一系列“电子事件”!实现这一目标的第一步是编译。

简单地说:编译时错误发生在这个阶段,而运行时错误发生在后面。

请记住:仅仅因为程序编译没有错误并不意味着它会运行没有错误。

运行时错误将发生在程序生命周期的准备、运行或等待部分,而编译时错误将发生在生命周期的“新建”阶段之前。

编译时错误示例:

语法错误 - 如果您的代码有歧义,如何将它们编译成机器级指令?您的代码需要 100% 符合语言的语法规则,否则无法编译为工作机器代码

运行时错误示例:

内存不足 - 例如,给定特定程度的变量,对递归函数的调用可能会导致堆栈溢出!编译器怎么能预料到这一点!?这不可以。

这就是编译时错误和运行时错误之间的区别


小智 6

作为其他答案的补充,这是我向外行解释的方式:

您的源代码就像一艘船的蓝图。它定义了船只的制造方式。

如果您将蓝图交给造船厂,而他们在造船时发现有缺陷,他们将停止造船,并在船舶离开船坞或接触水之前立即向您报告。这是一个编译时错误。该船甚至从未真正漂浮或使用其引擎。发现该错误是因为它甚至阻止了该船的制造。

当您的代码编译时,就好像飞船已经完成了。已建成并准备就绪。当您执行代码时,就像在远航中发射飞船一样。登上乘客,发动机在运转,船体在水上,所以这是运行时间。如果您的船有致命缺陷,使它在首次航行中沉没(或者可能为额外的麻烦而航行),则它会遇到运行时错误。


Ste*_*ger 5

例如:在强类型语言中,可以在编译时或运行时检查类型.在编译时,这意味着,如果类型不兼容,编译器会抱怨.在运行时意味着,您可以编译您的程序,但在运行时,它会抛出异常.


小智 5

简单地说,黑白差异就是编译时间和运行时间。

编译时:开发者以.java格式编写程序并转换成字节码,这是一个类文件,在这个编译过程中发生的任何错误都可以定义为编译时错误。

运行时:应用程序将生成的 .class 文件用于其附加功能,结果逻辑错误并引发错误,这是运行时错误


Ste*_*i J 5

编译时间: 将源代码转换为机器代码以使其成为可执行文件所需的时间称为编译时间。

运行时: 当应用程序运行时,称为运行时。

编译时错误是那些语法错误、缺少文件引用错误。运行时错误发生在源代码编译成可执行程序之后以及程序运行时。例如程序崩溃、意外的程序行为或功能不起作用。


小智 5

想象一下,你是一个老板,你有一个助手和一个女仆,你给他们一个任务清单,助手(编译时)会抓取这个清单并进行检查,看看任务是否可以理解,你没有用任何笨拙的语言或语法写作,所以他明白你想为一个工作分配某人所以他为你分配他并且他明白你想要一些咖啡,所以他的角色结束了女仆(运行时间)开始运行这些任务,所以她去给你泡咖啡,但突然间她没有找到任何可以煮的咖啡,所以她停止制作,或者她的行为不同并为你泡茶(当程序行为不同时,因为他发现了一个错误)。