以Java,C,Python为例浅谈编译型语言和解释型语言的区别

高级程序语言运行过程——以Java,C,Python为例

高级程序语言的分类

  1. 高级程序语言可分为解释型语言和编译型语言。

计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类,第一种是编译,第二种是解释。

  • 编译型语言:编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时不需要再翻译,而直接执行就可以了,最典型的例子就是C语言。
  • 解释型语言:解释型语言没有编译过程,而是在程序运行的时候,通过解释器对程序逐行做出解释,然后直接运行,最典型的例子是Ruby。
  1. ** 部分语言不能简单归为其中一类,而是两者的组合。**

随着语言的不断发展,很多语言不能简单的归为两类中的某一类,而是两者的混合。

  • Java:Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言
  • C#:C#首相是通过编译器将C#文件编译成IL文件,然后在通过CLR将IL文件编译成机器文件。所以我们说C#是一门纯编译语言,但是C#是一门需要二次编译的语言。同理也可以等效运用到基于.NET平台上的 其他语言。
  1. 编译型语言和解释型语言的优缺点。
  • 编译型语言在程序运行之前就已经对程序做出了“翻译”,所以在运行时就少掉了“翻译”的过程,所以效率比较高。
  • 一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化,从而在效率上超过编译型语言。

Java的运行

在这里插入图片描述

该图为菜鸟教程中Java部分的一张示意图。

图中的逻辑为未安装操作系统的机器,其中最主要的系统为BIOS系统,它是一组固化到计算机内主板上一个ROM芯片上的程序,它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息。 其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。

从图中可以看出,java程序的运行是不依赖与操作系统的,因为其执行过程(解释的部分)是通过虚拟机完成的,这也是为什么Java具有很好的可移植性的原因,只需再不同的操作系统中用不同的解释器(JVM)加以解释即可。下面具体介绍Java的运行流程。

  1. java程序执行过程分为两步,如下图所示。
  • 第一步:将java源码(.java文件)通过编译器(javac.exe)编译成JVM文件(.class文件)
  • 第二步:将JVM文件通过java.exe执行,输出结果
    在这里插入图片描述
    需要注意的是Java源文件的文件名需要和Java的类名保持一致(区分大小写),不然会报错。

C语言的运行

C语言是一种编译型语言,因为这一特性,所以C语言更接近底层(生成机器码文件),且具有更高的运行效率。C语言的编译流程如下。
在这里插入图片描述

  1. 预处理阶段
  • 处理所有的注释,以空格代替
  • 讲所有的#define删除,并且展开所有的宏定义
  • 处理条件编译指令#if,#ifdef、#elif,#else、#endif
  • 处理#include,展开文件包含
  • 保留编译器需要使用#pragma指令
  1. 编译阶段
  • 编译阶段对预处理文件进行语法分析、词法分析、语义分析。
    • 语法分析:分析表达式是否遵循语法规则
    • 词法分析:分析关键字,标识符,立即数是否合法
    • 语义分析:在语法分析基础上进一步分析表达式是否合法
  • 分析结束后进行代码优化生成相应的汇编代码文件
  1. 汇编阶段
  • 汇编器将汇编代码转变为机器可以执行的指令,也就是机器指令
  • 每条汇编指令几乎都对应一条机器指令
  1. 链接阶段
  • 链接是指将目标文件最终生成可执行文件,链接器的主要作用是把各个模块之间相互引用部分处理好,使得各个模块之间能够正确的链接,如下图所示
    在这里插入图片描述
  • 根据链接方式的不同,链接过程可以分为:
    • 静态链接:目标文件直接进入可执行文件
    • 动态链接:在程序启动后才动态加载目标文件,库的内容不会进入可执行程序

Python的运行

Python和Java一样,是一门先编译后解释的语言。

  1. Python运行过程中会出现的类型
  • PyCodeObject
    PyCodeObject则是Python编译器真正编译成的结果。
  • pyc文件
    pyc文件其实是PyCodeObject的一种持久化保存方式。

当Python程序运行时,编译的结果则是保存在位于内存中的PyCodeObject中,当Python程序运行结束时,Python解释器则将PyCodeObject写回到pyc文件中。
当Python程序第二次运行时,首先程序会在硬盘中寻找对应的pyc文件,如果找到,则直接载入,否则就重复上面的过程。
所以我们应该这样来定位PyCodeObject和pyc文件:pyc文件其实是PyCodeObject的一种持久化保存方式。
2. pyc文件何时会出现

  • pyc文件的目的
    我们之所以要把py文件编译成pyc文件,最大的优点在于我们在运行程序时,不需要重新对该模块进行再次解释。所以,需要编译成pyc文件的应该是那些可以重用的模块,这于我们在设计类时是一样的目的。所以Python的解释器认为:只有import进来的模块,才是需要被重用的模块。**所以,如果.py程序中没有被import,则不会产生.pyc文件,如果.py文件被import,则被import的文件会产生.pyc文件。
  1. pyc文件的过期时间
    pyc文件中写了一个Long型变量,变量的内容则是文件的最近修改日期,同理,在pyc文件中,每次在载入之前都会检查一下py文件和pyc文件保存的最后修改日期,如果不一致则重新生成新的pyc文件。
  2. 总结
  • 我们可以这样理解Python解释器的意图,Python解释器只是把我们可能重用到的模块持久化成pyc文件。
  • 在设计一个软件系统时,重用和非重用的东西是不是也可以分开来对待,这是软件设计原则的重要部分。
  • 将模块从主模块分开可压缩程序运行时间

各语言的运行流程有各自的特点,也各有其优势。理解各语言的运行流程,从而更好地写出高效的代码。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值