什么叫编译时和运行时
2012-10-24 15:52
190 查看
以前经常听说编译时和运行时的概念.但没太搞明白具体代表啥意思.后面花了点时间研究了下.总算知道个大概意思了.
那编译时就是简单的作一些翻译工作,比如检查老兄你有没有粗心写错啥关键字了啊.有啥词法分析,语法分析之类的过程.就像个老师检查学生的作文中有没有错别字和病句一样.如果发现啥错误编译器就告诉你.如果你用微软的VS的话,点下build.那就开始编译,如果下面有errors或者warning信息,那都是编译器检查出来的.所谓这时的错误就叫编译时错误,这个过程中做的啥类型检查也就叫编译时类型检查,或静态类型检查(所谓静态嘛就是没把真把代码放内存中运行起来,而只是把代码当作文本来扫描下).所以有时一些人说编译时还分配内存啥的肯定是错误的说法.
可能光讲概念你还是迷糊.还分别用C++和C#来举个简单点的例子.数组越界检查的例子(开发工具用的微软的VS)
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数据处理.)我一运行得到个吓人的数字,数了下貌似是十亿多.要是银行计算我的账户中有多少钱时也这样来个数组越界,搞个十多亿那我可发了啊.哎显然是想多了,还是老实敲代码吧.
int[] arr = { 1, 2, 3 };
int result = arr[4];
Console.WriteLine(result);
一编译还是正常通过.但一运行就报错了啊.C#与C++中不同,它有与运行时类型检查.会检查数组是否越界不.如果越界了不会给你返回个错误的结果,而是直接报错.你如果没有异常处理语句处理的话整个软件就挂掉了啊.
Father fa;
Son so;
fa = so;
fa.Fun(); //在编译时,实际上是把Fun当作Father类中的Fun看待.
//但在运行时实际上这里的Fun是调用的Son中的函数Fun.所以不做运行时类型检查是没法确定的啊.
编译时
编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如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.所以不做运行时类型检查是没法确定的啊.
相关文章推荐
- c进行预处理、编译、连接、运行是做什么
- java新手,什么情况下发生编译错误,什么情况下发生运行错误!
- 什么时运行时,什么是编译时?
- JavaScript是解释型语言,是不需要编译的,浏览器直接解释源代码,并执行在内存中创建变量等操作。不需要编译,即不存在什么语法不语法的,因为没有编译阶段,直接在运行的阶段才发现有没有语法错误
- 什么叫编译时和运行时
- NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?
- 编译时和运行时的对象分别是什么
- 什么叫编译时和运行时
- 求助:VB.NET2003,我RELEASE状态下编译可以通过,在DEBUG状态下却运行不起来。是什么原因呀?
- 精品赏析:一个.NET程序在编译和运行时都做了些什么?
- c进行预处理、编译、连接、运行是做什么
- NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?
- 什么叫编译时和运行时
- 使用动态分配和指针操作求 9 个 double 数的乘积(编译通过了,但是运行时出错,谁能帮我看看出了什么问题啊)[em08]
- c进行预处理、编译、连接、运行是做什么
- 什么是编译和运行
- 关于JAVA,特点,历史,编译式的语言&解释式的语言,什么是java?JDK?DOS?一次编译到处运行原理。
- Android编译过程中首先运行的是build/envsetup.sh脚本的作用是什么?
- java与c++程序在编译和运行上有什么区别