什么叫编译时和运行时

以前经常听说编译时和运行时的概念.但没太搞明白具体代表啥意思.后面花了点时间研究了下.总算知道个大概意思了.

编译时

编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字节码,C#中只有CLR能识别的MSIL.另外还有啥链接器.汇编器.为了了便于理解我们可以统称为编译器)

编译时就是简单的作一些翻译工作,比如检查老兄你有没有粗心写错啥关键字了啊.有啥词法分析,语法分析之类的过程.就像个老师检查学生的作文中有没有错别字和病句一样.如果发现啥错误编译器就告诉你.如果你用微软的VS的话,点下build.那就开始编译,如果下面有errors或者warning信息,那都是编译器检查出来的.所谓这时的错误就叫编译时错误,这个过程中做的啥类型检查也就叫编译时类型检查,或静态类型检查(所谓静态嘛就是没把真把代码放内存中运行起来,而只是把代码当作文本来扫描下).所以有时一些人说编译时还分配内存啥的肯定是错误的说法.

 

运行时

所谓运行时就是代码跑起来了.被装载到内存中去了.(你的代码保存在磁盘上没装入内存之前是个死家伙.只有跑到内存中才变成活的).而运行时类型检查就与前面讲的编译时类型检查(或者静态类型检查)不一样.不是简单的扫描代码.而是在内存中做些操作,做些判断.

 

 

举例说明

 

可能光讲概念你还是迷糊.还分别用C++和C#来举个简单点的例子.数组越界检查的例子(开发工具用的微软的VS)

 

C++中

 

int arr[] = {1,2,3};

int result = arr[4];

cout<<result<<endl;

 

上面的代码你一瞧你知道是错误的代码,数组越界了.但用编译器一编译,一点错都没.可见编译器其实还是挺笨的,还没你脑瓜子那么聪明啊.然后开始运行,Start Dubugging.于是报错了,于是你想虽然编译器笨了点,但运行起来时发现了错误也还不算太坏.但实际上运行时做数组的越界检查不是C++里面支持的特性,这里你dubug是VS中的一些工具给你做的检查.你如果点运行时选的是release而不是dubug的话会发现一切正常运行,但得到的结果不确定的.(因为你不知道arr[4]所指的内存里具有有啥数据.反正所以东东在内存中都是0101串嘛,你找到连续4个字节的一串0101来然后当成int数据处理.)我一运行得到个吓人的数字,数了下貌似是十亿多.要是银行计算我的账户中有多少钱时也这样来个数组越界,搞个十多亿那我可发了啊.哎显然是想多了,还是老实敲代码吧.

 

C#中

 

int[] arr = { 1, 2, 3 };

int result = arr[4];

Console.WriteLine(result);

一编译还是正常通过.但一运行就报错了啊.C#与C++中不同,它有与运行时类型检查.会检查数组是否越界不.如果越界了不会给你返回个错误的结果,而是直接报错.你如果没有异常处理语句处理的话整个软件就挂掉了啊.

 

为啥C++不在运行时做数组越界检查呢?

这应该主要是考虑到性能问题吧.C++设计之初为了达到与C差不多的效率.就尽量不会在运行时多做些额外的检查.因为这样无疑会降低性能的. 但有些地方却是必须得做运行时类型检查的.比如多态,你不在运行时做类型检查就没法搞定啊.举个简单例子吧.假如有父类Father,继承自Father的子类Son.这两个类中都有虚函数Fun.

Father fa;

Son so;

fa = so;

fa.Fun();   //在编译时,实际上是把Fun当作Father类中的Fun看待.

//但在运行时实际上这里的Fun是调用的Son中的函数Fun.所以不做运行时类型检查是没法确定的啊.

时间: 2025-01-21 06:50:45

什么叫编译时和运行时的相关文章

vb.net使用Listview显示数据,为何设计时和运行时显示的效果不一样?

问题描述 我用vb.net编写一个程序(使用.net2.0),使用了Listview控件来显示数据,设计的时候表头显示的很漂亮,但一到运行的时候就变得很难看了.这是设计的时候:这是运行的时候:.另外我发现其他人开发的程序也是用.net2.0,但它的表头就没变化.用Spy++来观查别人程序和我的程序的Listview控件,发现只在类名那里不同,我的程序的Listview的类名是WindowsForms10.SysListView32.app.0.bf7d44,别人程序的Listview类名是Win

运行时和编译时元编程—编译时元编程

原文链接    译文链接     译者:JackWang 运行时和编译时元编程 第二部分 2 编译时元编程 Groovy的编译时元编程支持编译时生成代码.这些变换(译者注:原文该专有名词是transformations,译者直译为变换,也许不准确.如果有知道准确翻译的读者恳请不吝赐教,待译者修正)叫做程序的抽象语法树(AST),在Groovy里,我们叫做AST变换.AST变换支持在编译过程中植入钩子,修改抽象语法树之后继续编译生成正常的字节码流.和运行时元编程相比,这种转换可以在类文件的修改可见

asp.net如何引用其他目录的程序集,并且编译时能通过

问题描述 我想把所有的DLL放到MyClassLib目录下,并且保证编译时和运行时都能通过,如何做?看过以前的贴子,我也把<runtime><assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1"><publisherPolicyapply="yes"/><probingprivatePath="MyClassLib"/></assemb

精品赏析:一个.NET程序在编译和运行时都做了些什么?

编译|程序 一个.NET程序在编译和运行时都做了些什么?================================================================在新闻组和邮件列表里有大量关于一个.Net程序的设计编译(design-time orrun-time)和运行原理 (CPU-specific binary or pseudo-code)的疑问. 这里是一个简单的回答:当你编译一个C#应用程序或任何一种CLS(CommmonLanguage Specificati

.NET编译时都做了一些什么

编译 ================================================================<br>FAQ - 一个.NET程序在编译和运行时都做了些什么?<br>================================================================<br>在新闻组和邮件列表里有大量关于一个.Net程序的设计编译(design-time or<br>run-time)和运行原

浅谈.NET编译时注入(C#--&gt;IL)

原文:浅谈.NET编译时注入(C#-->IL)      .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部分,从语言到MSIL的编译(我喜欢称为预编译),和运行时的从MSIL到本地指令,即时编译(JIT).JIT编译分为经济编译器和普通编译器,在这里就不多说了,不是本文的重点.本文主要讨论下预编译过程中我们能做的改变编译情况,改变生成的IL,从编译前后看看微软C#3.0一些语法糖,PostSharp

只有编译时,才能使用字符串常量池吗?心中的几个疑问。

问题描述 师兄,您好.下面是几个疑问,想问一下您,谢谢您!!publicclassTest{publicstaticvoidmain(String[]args){Stringstr1="HelloJava的长度:10";Stringstr2="Hello"+"Java"+"的长度:"+"HelloJava".length();System.out.println(str1==str2);intlen=10;

浅谈Java自定义注解和运行时靠反射获取注解_java

java自定义注解 Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能. 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annotation 包中. 1.元注解 元注解是指注解的注解.包括  @Retention @Target @Document @Inherited四种. 1.1.@Retention: 定义注解的保留策略 @Retention(RetentionPolicy.SOURCE) //注解仅

运行时和编译时元编程—运行时元编程

原文链接   译文链接   译者:JackWang 运行时和编译时元编程 第一部分 Groovy语言支持两种风格的元编程:运行时元编程和编译时元编程.第一种元编程支持在程序运行时修改类模型和程序行为,而第二种发生在编译时.两种元编程有各自的优缺点,在这一章节我们将详细讨论. 注:译者也是第一次接触Groovy,由于时间和水平有限(姑且让译者使用这个理由吧,对待知识本应该一丝不苟)部分专有名词可能翻译不准确甚至有误(读者阅读的过程中最好能参考原文),恳请读者不吝留言指出,谢谢! 1.运行时元编程