什么叫编译时和运行时

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

编译时

编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如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.所以不做运行时类型检查是没法确定的啊.

时间: 2024-10-13 18:09:04

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

编译和运行时的界限在哪儿?

两个概念: 一,编译单元:一个.java文件就是一个编译单元.一个.java文件会被编译成一个或多个.class文件.在eclipse等IDE中,默认自动编译,即,一旦.java文件被改动则重新编译并产生.class文件. 二,类的加载:一旦已运行的程序第一次访问一个类的静态数据或者创建一个类的对象时,jvm就会根据包名及类名到classpath下的对应文件夹中找到相应的.class文件将其加载到内存中,此时,程序进入运行时. 所以,编译期和运行时的物理边界是类的加载时. 如果一段程序在运行时每

探讨:编译时常量和运行时常量

编译时常量和运行时常量 C#有2种不同的常量定义方式:编译时常量(compile-time)和运行时常量(runtime).他们的行为方式有很大的不同,如果选用了错误的一个,那么将让程序的性能和正确性产生商榷.当然,一个系统最好没有任何问题,但是如果一定会存在一个问题,那么一个稍慢的但强壮的系统比一个速度更快的但很脆弱的系统要好.基于以上理由,在二者选其一的时候,你最好选择运行时常量. 运行时常量以 readonly 关键字定义,编译时是常量以 const 关键字定义: public const

关于指针变量编译和运行时

指针变量编译时只能运行编译时的方法,不能调用运行时类型的方法,即使它实际所指对象确实包含该方法. Father* fa=[[Son alloc]init]; 编译时是:Father 运行时时:Son 解决方法: 强制转换成子类类型,这样 编译和运行时的类型就相同了 //下面编译时类型和运行时类型不一样,多态发生 FKBase* ploymophicBc=[[FKSubclass alloc]init]; [ploymophicBc base]; [ploymophicBc test]; //FK

in C#,编译型常量(const)和运行时常量(readonly)

readonly 关键字与 const 关键字不同. const 字段只能在该字段的声明中初始化. readonly 字段可以在声明或构造函数中初始化. 因此,根据所使用的构造函数, readonly 字段可能具有不同的值. 另外, const 字段是编译时常量,readonly 字段为运行时常量. 你应该尽量使用运行时常量.原因是变异性常量虽然性能稍微快一些.但是却没有 运行时常量那么灵活.就像第一段中所说,使用readonly时,根据使用的构造函数, readonly字段可能具有不同的值.

编译和运行时,库在何处

在编译程序是,-L或者-l直接指明,搜索库在/lib /usr/lib 寻找,或者在LD_LIBRARY_PATH(包括/etc/ld.so.conf)中指明,以及用pkg-config工具的配置文件和变量PKG_CONFIG_PATH指明, 为了加速寻找LD_LIBRARY_PATH下的库,/etc/ld.so.conf还有个缓存,/etc/ld.so.cache,用ld-config来管理. 程序在运行搜索库时,主要向这几个地方找,LD_LIBRARY_PATH或者ld.so.conf的配置

【特种兵系列】编译时与运行时

在开发和设计的时候,我们需要考虑编译时,运行时以及构建时这三个概念.理解这几个概念可以更好地帮助你去了解一些基本的原理.下面是初学者晋级中级水平需要知道的一些问题. Q.下面的代码片段中,行A和行B所标识的代码有什么区别呢? public class ConstantFolding { static final int number1 = 5; static final int number2 = 6; static int number3 = 5; static int number4= 6;

Java编译期和运行期

Q.下面的代码片段中,行A和行B所标识的代码有什么区别呢? ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class ConstantFolding {       static final  int number1 = 5;       static final  int number2 = 6;       static int number3 = 5;       static int number4= 6;       

编译时类型与运行时类型

1.编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定. 当编译时类型和运行时类型不一致时,就会出现所谓的多态. 因为子类是一个特殊的父类,因此java允许把一个子类对象直接赋给一个父类的引用变量,无需任何类型转换(向上转型) 引用变量在编译阶段只能通过编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法.因此,编写java代码时,引用变量只能 调用声明该变量时所用类里包含的方法. 2.编写程序时,引用变量只能调用它编译时类型的方法,而不能调用运行时类型的方法

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

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