运行时间与编译时间

任何人都可以请给我一个很好的理解什么是运行时间和编译时间之间的区别?

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

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

编译时间

  1. 该程序不需要满足任何不变量。 事实上,它根本不是一个完整的程序。 你可以喂这个HTML的编译器,看着它吧…
  2. 在编译时会出现什么问题:
    • 语法错误
    • 类型检查错误
    • (很少)编译器崩溃
  3. 如果编译成功,我们知道什么?
    • 该程序是完整的 – 一个有意义的程序在任何语言。
    • 开始运行程序是可能的。 (该程序可能会立即失败,但至少我们可以尝试。)
  4. 什么是输入和输出?
    • 输入是正在编译的程序,以及需要导入才能编译的任何头文件,接口,库或其他voodoo。
    • 输出是希望汇编代码或可重定位的对象代码,甚至是一个可执行程序。 或者如果出现错误,输出是一堆错误消息。

运行

  1. 我们对程序的不变量一无所知 – 它们是程序员所做的任何事情。运行时不变量很少由编译器单独执行; 它需要程序员的帮助。
  2. 运行时错误是什么?

    • 被零除
    • 解引用空指针
    • 内存不足

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

    • 试图打开一个不存在的文件
    • 尝试找到一个网页,发现一个所谓的网址不正确
  3. 如果运行成功,程序结束(或继续)而不会崩溃。
  4. 输入和输出完全取决于程序员。 文件,屏幕上的窗口,网络数据包,发送到打印机的作业,你的名字。 如果程序启动导弹,这是一个输出,它只发生在运行时间:-)

我从错误的角度思考它,什么时候能够被抓住。

编译时间:

string my_value = Console.ReadLine(); int i = my_value; 

一个字符串值不能被分配一个int类型的变量,所以编译器在编译时确定知道这个代码有问题

运行:

 string my_value = Console.ReadLine(); int i = int.Parse(my_value); 

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

编译时间:开发人员正在编译代码的时间段。

运行时间:用户运行你的软件的时间段。

你需要更清晰的定义吗?

编辑 :以下适用于C#和类似的强类型编程语言,我不确定这是否有帮助)。

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

 int i = "string"; --> error at compile-time 

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

 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 

将源代码翻译成东西发生在[screen | disk | network]上可以(大致)两种方式发生; 称他们编译和解释。

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

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

第一步发生的事情据说发生在“编译时”,第二步发生的事情据说发生在“运行时”。

在一个解释的程序(例如MicroSoft基本(在DOS)和Python(我认为)):

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

在这种情况下,编译时间和运行时间之间的差异很难确定下来,而且与程序员或用户的关系更少。

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

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

基本上,如果你的编译器能够解决你的意思,或者“在编译时”它的值是什么,那么它可以将这个代码硬编码到运行时代码中。 很显然,如果你的运行时代码每次运行的时候都要做一个计算,所以如果你可以在编译时确定一些东西,那就好多了。

例如。

持续折叠:

如果我写:

 int i = 2; i += MY_CONSTANT; 

编译器可以在编译时执行这个调用,因为它知道2是什么以及MY_CONSTANT是什么。 这样就可以避免每一次执行就执行一次计算。

从前面的问题类似的回答之后运行时错误和编译器错误有什么区别?

编译/编译时间/语法/语义错误:编译或编译时错误是由于输入错误而发生错误,如果我们不遵循任何编程语言的正确语法和语义,则编译器会抛出编译时错误。 他们不会让你的程序执行一行,直到你删除所有的语法错误,或者直到你调试编译时错误。
例如:在C中丢失一个分号,或者把int作为Int

运行时错误:运行时错误是程序处于运行状态时生成的错误。 这些类型的错误将导致您的程序意外行为,甚至可能会杀死您的程序。 他们经常被称为例外。
示例:假设您正在读取一个不存在的文件,将导致运行时错误。

阅读更多关于这里的所有编程错误

编译时间:

在编译时所做的事情在运行结果程序时几乎没有成本,但在构建程序时可能会产生很大的成本。

运行:

或多或少的完全相反。 当你建立的时候花费很少,当程序运行的时候花费更多。

从另一面; 如果在编译时进行了一些操作,它只能在你的机器上运行,如果有什么是运行时的,它就会在你的用户机器上运行。

关联

一个重要的例子就是一个单位携带型。 编译时版本(比如Boost.Units或者D版本 )最终会像使用本机浮点代码一样快速地解决问题,而运行时版本最终需要打包一个值,并且在每个操作的旁边执行检查。 另一方面,编译时间版本请求者在编译时知道值的单位,并且不能处理来自运行时输入的情况。

嗯,好吧,运行时是用来描述程序运行时发生的事情。

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

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

简单的字差b / w编译时间和运行时间。

编译时间:开发人员用.java格式编写程序,并将其转换为类文件的Bytecode,在编译过程中发生的任何错误都可以定义为编译时错误。

运行时间:生成的.class文件被应用程序用于其额外的功能,并且逻辑结果是错误的,并引发错误,这是一个运行时错误

编译时间:

在编译时所做的事情在运行结果程序时几乎没有成本,但在构建程序时可能会产生大量成本。 运行:

或多或少的完全相反。 你建造的时候花费很少,运行程序时花费更多。

从另一面; 如果在编译时进行了一些操作,它只能在你的机器上运行,如果有什么是运行时的,它就会在你的用户机器上运行。

下面是关于编程主题“JAVA编程入门”作者Daniel Liang的一段引文:

“用高级语言编写的程序称为源程序或源代码,由于计算机不能执行源程序,所以必须将源程序翻译机器代码才能执行 ,可以使用另一种编程工具一个解释器或一个编译器“ 。 (Daniel Liang, “JAVA编程入门” ,第8页)。

他继续…

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

当我们打高级/人类可读的代码时,这首先是无用的! 它必须被翻译成你的微小的CPU中的一系列“电子事件”! 第一步是编译。

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

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

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

编译时错误的示例:

语法错误 – 如果您的代码不明确,您的代码如何编译为机器级别的指令? 你的代码需要100%符合语言的语法规则,否则不能编译成工作机器代码 。

运行时错误的示例:

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

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

运行时间意味着运行程序时会发生一些事情。

编译时间意味着编译程序时会发生一些事情。

下面是对“运行时间与编译时间之间的区别”这个问题的回答的扩展。 – 与运行时间和编译时间相关的开销的差异?

产品的运行时性能通过更快地交付结果来提高质量。 通过缩短编辑 – 编译 – 调试周期,产品的编译时性能有助于及时。 但是,运行时间性能和编译时间性能是实现及时质量的次要因素。 因此,只有在整体产品质量和及时性得到改善的情况下,才能考虑运行时间和编译时间的性能改进。

这里进一步阅读的一个很好的来源:

我一直认为它与程序处理开销有关,以及它如何影响性能,如前所述。 一个简单的例子是,无论是在代码中定义我的对象所需的绝对内存。

一个定义的布尔值需要x内存,然后在编译的程序中,不能改变。 当程序运行时,它确切地知道为x分配多少内存。

另一方面,如果我只是定义一个通用的对象类型(即一种未定义的占位符,或者可能是一个巨大的blob指针),我的对象所需的实际内存是不知道的,直到程序运行,我给它分配的东西,因此必须对它进行评估,然后在运行时动态处理内存分配等(更多的运行时间开销)。

如何动态处理将取决于语言,编译器,操作系统,代码等。

在那个笔记上,但是它确实取决于你使用运行时间和编译时间的上下文。

我们可以根据不同的两大类将这些分类为静态绑定和动态绑定。 它是基于绑定何时完成对应的值。 如果引用在编译时被解析,那么它就是静态绑定,如果引用在运行时被解析,那么它就是动态绑定。 静态绑定和动态绑定也被称为早期绑定和后期绑定。 有时它们也被称为静态多态性和动态多态性。

约瑟夫·库兰代

运行时间和编译时间之间的主要区别是:

  1. 如果代码中有任何语法错误和类型检查,则会引发编译时错误,其中 – 执行时间:执行代码后检查。 例如:

int a = 1 int b = a/0;

这里第一行最后没有分号—>执行程序时编译时间错误,执行操作b,结果无限—>运行时错误。

  1. 编译时间不会查找您的代码提供的功能的输出,而运行时则可以。

这是一个非常简单的答案:

运行时间和编译时间是编程术语,指的是软件程序开发的不同阶段。 为了创建一个程序,开发人员首先编写源代码,它定义了程序的功能。 小程序可能只包含几百行源代码,而大型程序可能包含数十万行源代码。 源代码必须编译成机器代码才能成为可执行程序。 这个编译过程被称为编译时间(把编译器当作翻译器)

编译好的程序可以被用户打开并运行。 当应用程序正在运行时,它被称为运行时。

术语“运行时”和“编译时间”通常被程序员用来指代不同类型的错误。 编译时错误是一个问题,例如语法错误或缺少文件引用,导致程序无法成功编译。 编译器会产生编译时错误,并且通常指示源代码的哪一行导致该问题。

如果一个程序的源代码已经被编译成一个可执行程序,它可能在程序运行时仍然会出现错误。 示例包括不起作用的功能,意外的程序行为或程序崩溃。 这些类型的问题被称为运行时错误,因为它们在运行时发生。

参考

这不是一个好的问题(这不是一个具体的编程问题),但一般来说这不是一个坏问题。

如果你认为这是微不足道的:阅读时间和编译时间,这是一个有用的区别是什么? 编译器在运行时可用的语言呢? Guy Steele(他不是虚拟的)在CLTL2中写了7页关于EVAL-WHEN的文章,CL程序员可以用它来控制这个。 2句话对于一个定义来说勉强够用,而这个定义本身还远远不够解释

总的来说,语言设计者似乎试图避免的是一个棘手的问题。 他们经常只是说:“这是一个编译器,它编译时间的东西,之后的一切都是运行时间,玩得开心”。 C被设计成易于实现,而不是最灵活的计算环境。 如果在运行时没有可用的编译器,或者可以轻松地控制何时对表达式进行评估,那么您最终会用语言中的黑客来伪造宏的常见用法,或者用户拿出Design Patterns来模拟有更强大的构造。 一个简单实现的语言绝对是一个有价值的目标,但这并不意味着它是编程语言设计的最终结果。 (我不使用EVAL-WHEN,但是没有它,我无法想象生活。)

编译时间和运行时间的问题空间很大,而且在很大程度上还没有探索。 这并不是说这个讨论是正确的,但是我鼓励人们进一步探索这个领域,特别是那些没有先入为主的观点。 这个问题既不简单也不傻,我们至少可以把调查人员指向正确的方向。

不幸的是,我不知道这方面有什么好的参考。 CLTL2谈了一下,但是了解它并不是很好。