编译型语言和解释型语言(一)

作者: HaleyLiu | 来源:发表于2017-10-22 15:19 被阅读33次

    首先,我们编程都是用的高级语言(写汇编和机器语言的大牛们除外),计算机不能直接理解高级语言,只能理解和运行机器语言,所以必须要把高级语言翻译成机器语言,计算机才能运行高级语言所编写的程序。

    一.先说说编译型语言

    1.定义:  
    程序在执行之前需要一个专门的编译过程,把程序编译成为
    机器语言的文件,运行时不需要重新翻译,直接使用编译的
    结果就行了。程序执行效率高,依赖编译器,跨平台性差些。
    2.有哪些编译型语言:
    C/C++、Pascal/Object Pascal(Delphi)、Golang
    典型的就是它们可以编译后生成.exe文件,之后无需再次  
    编译,直接运行.exe文件即可。
    3.例子:(C和C++)
    以C语言为例:
    #include<stdio.h>  
    int main(){
        printf("helloword");
        return 0;
    }  
    安装mingw-get-setup.exe安装gcc和g++,C语言用gcc命令来编译
    
    path配置gcc的环境变量.PNG 编译C程序生成exe并执行.PNG 生成exe文件.PNG
    以C++语言为例:
    #include <iostream> 
    using namespace std;
    int main()  
    {  
        cout<<"hello atom"<<endl; 
        return 0;  
    }  
    上面已经安装了mingw-get-setup,用的是g++命令来编译
    
    编译C++程序生成exe并执行.PNG 生成exe文件.PNG

    2.然后再来说说解释型语言

    1. 定义:程序不需要编译,程序在运行时才翻译成机器语言,每执行  
    一次都要翻译一次。因此效率比较低。在运行程序的时候才翻译,专门有  
    一个解释器去进行翻译,每个语句都是执行的时候才翻译。效率比较低,  
    依赖解释器,跨平台性好.
    2.有哪些解释型语言:Java、C#、PHP、JavaScript、VBScript、  
    Perl、Python、Ruby、MATLAB 等等
    

    3.例子:
    (1)以Java为例(解释型+编译型语言)
    java是通过javac.exe编译成.class文件 然后通过jvm加载.class文件,然后调用java.exe执行文件。在此之前你要下载安装JDK并配置环境变量。

    public  class  Test{
        public static  void main(String args[]){
            System.out.println("Hello");
        }
    }
    
    编译java文件.png 执行java文件.png

    (2)以C#为例(解释型语言)

    讲到C#必须要说到CLR和.NET FrameWork。.Net是一种解决方案; C#  
    是.Net解决方案中的一种语言; CLR是.Net的运行架构.
    《1》CLR是公共语言运行库(Common Language Runtime)和Java虚拟机  
    一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集等),并保  
    证应用和底层操作系统之间必要的分离。
    《2》.NET FrameWork的核心是其运行库执行环境,称为公共语言运行库(Common Language Runtime)。
    《3》作用:
    (1)CLR是一个类似于JVM的虚拟机,为微软的.Net产品提供运行环境。
    (2)CLR上实际运行的并不是我们通常所用的编程语言(例如C#、VB等),而是一种字节码形态的“中间语言”。  
    这意味着只要能将代码编译成这种特定的“中间语言”(MSIL),任何语言的产品都能运行在CLR上。
    (3)CLR通常被运行在Windows系统上,但是也有一些非Windows的版本。这意味着.Net也很容易实现  
    “跨平台”。(至于为什么大家的印象中.Net的跨平台性不如Java,更多的是微软商业战略导致的)。
    语言支持:
    微软已经为多种语言开发了基于CLR的编译器,这些语言包括:C++/CLI、C#、Visual Basic、F#、  
    Iron Python、 Iron Ruby和IL。除此之外,其他的一些公司和大学等机构也位一些语言开发了基于CLR  
    的编译器,例如Ada、APL、Caml、COBOL、Eiffel、Forth、Fortran、Haskell、Lexicon、LISP、  
    LOGO、Lua、Mercury、ML、Mondrian、Oberon、Pascal、Perl、PHP、Prolog、RPG、Scheme、  
    Smaltak、Tcl/Tk。
    CLR为不同的编程语言提供了统一的运行平台,在很大程度上对上层开发者屏蔽了语言之间才特性差异。  
    对于CLR来说,不同语言的编译器(Compiler)就相当于一个这种语言的代码审查者(Checker),所做的  
    工作就是检查源码语法是否正确,然后将源码编译成CLR所需要的中间语言(IL)。所以编程语言对于CLR  
    是透明的,也就是说CLR只知道IL的存在,而不知道IL是由哪种语言编译而来。
    功能:
    (1)基类库支持 (Base Class Library Support)
    (2)内存管理 (Memory Management)
    (3)线程管理 (Thread Management)
    (4)垃圾回收 (Garbage Collection)
    (5)安全性 (Security)
    (6)类型检查 (Type Checker)
    (7)异常处理 (Exception Manager) 
    (8)即时编译 (JIT)
    
    using System;
    namespace Animal
    {
        public class Cat
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("cat");
            }
        }
    }
    
    csc.exe编译C#命令.png 调用csc命令编译.png

    vb的解释器CLR

    vbc.png

    (3)脚本语言也是解释型语言,比如vbscript,javascript,installshield script,ActionScript等等,脚本语言不需要编译,可以直接用,由解释器来负责解释。
    例如javascript:

        JavaScript引擎,不是逐条解释执行javaScript代码,而是按照代码块  
    一段段解释执行。所谓代码块就是使用<script>标签分隔的代码段。
    
    编译阶段:
        对于常见编译型语言(例如:Java)来说,编译步骤分为:词法分析->  
    语法分析->语义检查->代码优化和字节生成。
    
        对于解释型语言(例如JavaScript)来说,通过词法分析和语法分析得到  
    语法树后,就可以开始解释执行了。
    
    (1)词法分析是将字符流(char stream)转换为记号流(token stream),就  
    像英文句子一个个单词独立翻译,举例:
    
    代码:var result = testNum1 - testNum2; 
    
    词法分析后 :
    
        NAME "result"  
        EQUALS  
        NAME "testNum1"  
        MINUS  
        NAME "testNum2"  
        SEMICOLON 
    
    (2)语法分析得到语法树,举例:
        条件语句 if(typeof a == "undefined" ){ a = 0; } else { a = a; } alert(a);
    当JavaScript解释器在构造语法树的时候,如果发现无法构造,就会报语  
    法错误,并结束整个代码块的解析。
    
     (3)“预编译”(并非完全的顺序执行)
        “function函数”是一等公民!编译阶段,会把定义式的函数优先执行,  
    也会把所有var变量创建,默认值为undefined,以提高程序的执行效率!
    
    总结:当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量  
    和函数进行处理!并且是先预声明变量,再预定义函数!
    
    JavaScript执行过程:
    
     二、JavaScript执行过程
    
     在解释过程中,JavaScript引擎是严格按着作用域机制(scope)来执行  
    的。JavaScript语法采用的是词法作用域(lexcical scope),  
    也就是说JavaScript的变量和函数作用域是在定义时决定的,  
    而不是执行时决定的,由于词法作用域取决于源代码结构,所以  
     JavaScript解释器只需要通过静态分析就能确定每个变量、函数  
    的作用域,这种作用域也称为静态作用域(static scope)。  
    补充:但需要注意,with和eval的语义无法仅通过静态技术实现,  
    实际上,只能说JS的作用域机制非常接近lexical scope。
    
    JavaScript中的变量作用域在函数体内有效,无块作用域;
    
    function func(){
        for(var i = 0; i < array.length; i++){  
           //do something here.  
        }  
        //此时i仍然有值,及i== array.length  
        print(i);//如果在java语言中,则无效
    }
    
        JavaScript引擎在执行每个函数实例时,都会创建一个  
    执行环境(execution context)。  
    执行环境  中包含一个调用对象(call object), 调用对   
    象是一个scriptObject结构    
    (“运行期上下文”),用来保存内部变量表varDecls、  
    内嵌函数表  funDecls、父级引用列表upvalue等  
    语法分析 结构(注意:varDecls  
    和funDecls等信息是在语法分析阶段就已经得到,并  
    保存在语法树中。  
    函数实例执行时,会将这些信息从语法树复制到  
     scriptObject上)。  
    scriptObject是与函数相关的一套静态系统,与函数实  
    例的生命周期  
    保持一致,函数执行完毕,该对象销毁。
    
        JavaScript引擎通过作用域链(scope chain)把多个  
    嵌套的作用域串连在一起,并借助这个链条帮助JavaScript  
    解释器检索变量的值  。这个作用域链相当于一个索引表,  
    并通过编号来存 储它们的嵌套关系。当JavaScript解释器  
    检索变量的值,会按着这个索引编号进行  
    快速查找,直到找到全局对象(global object)为止,如  
    果没有找到值,则传递一个特殊的undefined值。
    
    案例分析:
    
    var scope = "global";
    scopeTest();
    function scopeTest(){  
        alert(scope);  
        var scope = "local";  
        alert(scope);  
    }
    
    打印结果:undefined,local;
    分析:省略词法分析等过程...执行遇到函数调用scopeTest(),  
    创建一个调用对象(运行期上下文,函数执行完毕,该对象销毁)  
    ,构造它的作用域链时,搜索函数中用var声明的变量放入该链(  
    在语法分析阶段就已经得到放在语法树中,此时只是拷贝过来)  
    ,因此scope在整个函数 
    scopeTest内都是可见的(从函数体的第一行到最后一行)。虽  
    然函数scopeTest的作用域链上有全局对象,自然能够访问  
    到全局的scope, 但寻找变量时会沿着自身作用域链向上  
    逐个找,因此首先找到自己的scope:undefined。 
    
        如果函数引用了外部变量的值,则JavaScript引擎会为该函数创建  
    一个闭包体(closure),闭包体是一个完全封闭和独立的作用域,  
    它不会在函数调用完毕后就被JavaScript引擎当做垃圾进行回收。  
    闭包体可以长期存在,因此开发人员常把闭包体当做内存中的蓄水  
    池,专门用来长期保存变量的值。只有当闭包体的外部引用被全部  
    设置为null值时,该闭包才会被回收。当然,也容易引发垃圾泛滥,  
    甚至出现内存外溢的现象。
    

    相关文章

      网友评论

        本文标题:编译型语言和解释型语言(一)

        本文链接:https://www.haomeiwen.com/subject/xlocyxtx.html