第5章 基础——5.1. 从代码程序

白话C++

第5章. 基础

总有一些知识,要在多年以后,我们才能感受得到它的力量。

 

5.1.从代码到程序

这是一行代码:

   cout<< "Hello world!" << endl;

它是如何变成一段程序,从而在屏幕上打出“Hello world”呢?

从一行文字代码,最后演变到一个硬件动作,我们无法在本收细究这一过程,但其中重要的一步却必须理解:

高级语言写成的程序代码,必须“转变”成机器语言,才有可能让机器执行——为什么电脑只懂得机器语言?之前我们已经学习过:因为机器语言只有的0和1,可以直接转化成硬件状态变化,比如通电、断电)。

〖重要〗: 我们写的程序,真的能直接操作硬件吗?

能直接操作硬件的PC(个人电脑)程序,已经是很早以前的事了。事实上,现在在一台个人电脑上,能直接操作硬件的,只有“操作系统”,而其它的应用程序,通常都需要通过操作系统的编程接口(API),或者在操作系统的“监管之下”,访问硬件。

 

将源代码,转换为“机器语言”,当前存在三种常见的方法:编译、翻译、虚拟机。

5.1.1. 编译

首先需要一个被称为“编译器”的程序;然后,将(程序员)编写好的代码,交给编译器编译,编译结果得到一个新的应用程序。

成果是:新的应用程序也可以直接运行,不再需要编译器,更不再需要源代码,就可以和操作系统打交道。

jg1

图 5-1 代码编译成程序,程序可以直接访问操作系统、甚至硬件

 

如果用自然语言的翻译工作来比喻,那么,编译型程序相当于“笔译”:假设你要和一位英国客户打交道,你用中文写了你要说的话,然后请一位翻译家(编译器),将它笔译成英文稿,交给客户(操作系统)。

  • 缺点

第一、如果换了讲另一种语言的客户,我们很可能需要另请一位翻译家——换一个操作系统,需要换一种编译器。

第二、比现实中的翻译还要惨的一点是,如果换一个操作系统,我们就一定要手头有那个操作系统,才有可能编译出可以在该操作系统上运行的程序。

第 三、如果一开始只想着翻译成英文,那么可能用了太多的英国典故,这样,用英文表达是一篇优美的文章;可能在翻译到法文时,有些语句会变得别扭,甚至有些典 故根本翻译不了——在Windows下能编译的C++程序,可能在Linux下编译不了,特别是当你一开始时根本没有想到跨平台的问题。

第 四、在最初的交流时,显得效率很差,因为你每次都完整地表达在纸上,然后交给翻译——程序不可能一下子就写得100%正确,对于编译型的程序来说,最初的 调试效率比较差,往往要反复的改程序,然后编译,看结果是否正确等,编译器会严格地挑出你语法上的错误,但几乎不能直接为你找出内容上的问题。

  • 优点

第一、谈判完成,你的客户就可以在任意时刻,任意地方,直接阅读文稿,不需要经常向你为他配一位翻译——一切正常之后,你的程序就可以独立运行了,不再需要编译器。

第二、既然你的客户可以直接阅读文稿,那通常这也就是效率最高的方法——没错,编译出来的程序,不需每次都解释一次,所以在运行效率上,具备先天优势。

第 三、你可以尽情使用你的目标客户所懂得的典故来增加的文章的精彩。比如你要举一位英雄,对美国客户,你可以举华盛顿,对法国,你可以举拿破仑。另外,因为 是笔译,你的翻译有的时间和精力来优化你文稿——这里的意思是:因为事先知道要翻译成哪个操作系统的程序,所以你可以深入挖掘出该目标操作系统的各种功 能。

5.1.2. 解释

首先需要一个被称为“解释器”的程序;然后将写好的代码,交给解释器解释,根据代码的需要,由解释器向操作系统打交道。

结果是:通常这种情况下,“解释器”和“代码”合起来,被叫成“程序”,但我们知道,并没有实际可以自运行的新程序产生。

jg2

图 5-2 程序被解释执行,只能经由解释器和操作系统打交道

 

如 果用自然语言的翻译工作来比喻,那么,解释型程序相当于现场“口译”:你说上一段,然后翻译家就立即翻译给客户听。不过,比较糟糕的是,这个过程中,只记 下你的口述的内容,并不记载翻译后的内容(包括客户自己也不记),于是每次客户想再了解一下你说过的内容,就必须找到翻译重新翻译。

  • 缺点

第 一、客户要一直带着翻译,较好情况下,多份文档可以同用一个翻译,最差情况下,每一份文档都得配上一位翻译,客户身边围着一堆翻译(而不是保镖),又累 赘,又失面子——常有这种事发生:你写一个200K的大小的“程序”,安装时却要带数十兆大小的“解释器”,你烦,你的用户也烦。

第二、运行效率太差,太明显了,根本不必再打比喻。

第三、口译,相比笔译,准确性会有所下降。你可能说着说着,直到很后面了,才发现前面说过的某句话有问题——相比编译器的严格语法要求,解释型程序往往对语法要求比较宽松,这有时是好事,但也有可能是坏事。(当然,也有存在既是翻译型,又有严格语法检查的程序)。

第四、因为中间时时隔着一位翻译,因此当有特定需要时,经常会觉得像是在隔靴搔痒,使上不劲儿——“解释器”可能事先配置了100用个功能,但当你需要第101个功能时,你就会发现它非常难以实现。

  • 优点

第一、因为是口译,简单处说上一大段再翻译,困难处则说一句译一句,再听一句客户的反馈,这个交流过程比较通畅——解释型程序,在初期调试阶段,往往效率比较高。

第二、不需要事先在特定的操作系统上编译,这就使用解释型程序先天具备跨平台的优势。另外,有些需求的解释型语言,通常会在语法实现上,及在库功能实现上,做出包装或剪裁,再加上为不同的操作系统定制一个解释器,所以多数解释型语言,都有较好的跨平台能力。

5.1.3. 虚拟机

软 件界的“虚拟机”有两种:一种是针对用户(人)的虚拟机,比如VMware软件,它可以在一台机器上,模拟成两台电脑,这“两台电脑”还可以同时运行,并 且可以使用不同的操作系统。另外一种虚拟机,是此时我们所讲的,它只是针对“程序”模拟出一台机器,它的目的是让程序可以不去理会自己运行在什么硬件,什 么操作系统之上。

〖小提示〗:“编译、解释、虚拟机”可以并列吗?

把“虚拟机”和“编译、解释”并列其实不太合理。因为在“虚拟机”的世界里,同样还可以包含“编译型”程序和“解释型”程序两种。不过,如果仅仅考虑最终程序是如何运行的,则虚拟机确实可以独立为一种方法。

 

从下图中我们看到,“虚拟机”在程序和操作系统之间,又增加了一个隔离层。在隔离层里,代码可以采用“编译”的方式编译成程序。但仅仅是编译成“虚拟机”的程序。

图 5-3 代码被“编译”成虚拟机里的“程序”

 

虚拟机里的 “程序”仅可以直接访问虚拟机资源,真正和操作系统或硬件打交道的,是虚拟机,因此,将虚拟机看成是一个更强的“解释器”,也无不妥。反过来,之前一些典型的解释型语言,比如Python,随着其解释器越来越强大,有时候人们也把它当作是一种“虚拟机”。

直觉上,虚拟机的存在,必然会带来程序运行更加缓慢,也确实是虚拟机很长一段时间的表现;不过,随着虚拟机技术的进步,程序的速度也在提高。

另外一个直觉,虚拟机的存在,大大增强了程序的跨平台运行能力,这也正是采用虚拟机的重要目的之一,Java的口号就是:“一次书写,到处运行”。

有关虚拟机的优缺点,不再罗列。

〖小提示〗:虚拟机上的程序真的“一次书写,到处运行”吗?

由于不同操作系统上的虚拟机,或者不同产家开发的虚拟机之间,仍然存在一些差异,这些会给程序跨平台运行时,带来一些相对隐秘的问题,因此在实际上系统进行试运行,调试,以至修改部分代码,也是常见的事。

另一方面,类似.NET这样的虚拟机,由于商业利益点不同,所以它的主推者(微软),并没有主动推行跨平台的实现。

 

白话C++
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南郁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值