一.认识程序
旅行前,我们要先熟悉地名,知道去哪里旅行,将会经过哪里。学习编程语言也一样,在学习之前要先了解程序、调试、语法错误、运行错误、语义错误等知识。
程序:
我们都知道,出门旅行肯定要选择交通工具,现在常用的交通工具有飞机、火车、轮船、汽车等,我们会根据自己的喜好和一些其他因素选择对应的交通工具。
编程语言也一样,我们选择一门编程语言就相当于选择一种交通工具,那么,编程语言的“交通”工具是什么呢?是程序。
程序是指根据语言提供的指令按照一定逻辑顺序对获得的数据进行运算,并最终返回给我们的指令和数据的组合。在这里,运算的含义是广泛的,既包括数学计算之类的操作(如加减乘除),又包括寻找和替换字符串之类的操作。数据依据不同的需要组成不同的形式,处理后的数据也可能以另一种方式体现。
程序是用语言写成的。语言分高级语言和低级语言。
低级语言有时叫机器语言或汇编语言。计算机真正“认识”并能够执行的代码,在我们看来是一串0和1组成的二进制数字,这些数字代表指令和数据。早期的计算机科学家就是用这些枯燥乏味的数字编程。低级语言的出现是计算机程序语言的一大进步,它用英文单词或单词的缩写代表计算机执行的指令,使编程的效率和程序的可读性都有了很大提高,但它仍然和机器硬件关联紧密,不符合人类的语言和思维习惯,而且要想把用低级语言写的程序移植到其他平台,就必须重写。
高级语言的出现是程序语言发展的必然结果,也是计算机语言向人类的自然语言和思维方式逐步靠近和模拟的结果。由于高级语言是对人类逻辑思维的描述,用高级语言写程序会感到比较自然,读起来也比较容易,因此现在大部分程序都是用高级语言写的。
高级语言设计的目的是让程序按照人类的思维和语言习惯书写,是面向人的,而不是面向机器。我们用着方便,机器却无法读懂,更谈不上运行。所以,用高级语言写的程序必须经过“翻译”程序的处理,将其转换成机器可执行的代码,才能运行在计算机上。如果想把高级语言写的程序移植到其他的平台,只需在它的基础上做少量更改就可以了。
高级语言翻译成机器代码有两种方法,即解释和编译。
解释型语言是边读源程序边执行。高级语言就是源代码。解释器每次会读入一段源代码,并执行它,接着再读入并执行,如此重复,直到结束,图2-1显示了解释器的结构。这个有点类似在乡村里搭乘公交,只要碰到路上有人等公交,就停下来载人。
编译型语言是将源代码完整的编译成目标代码后才能执行,以后在执行时不需要再编译。图显示了一个编译器的结构,这个有点类似我们乘坐的直达车,所有要乘车的人都从起点上车,中途不再搭载其他乘客。
调试:
每当远游时,司机肯定要做几件事情,如检查发动机是否正常、检查油箱、检查各项安全系统和液压系统等,为的是尽可能减少在路途中发生意外情况。
我们编程也是一样的,需要经常做检查。有一些问题编译器会帮助我们检查出来,问题查出后,简单的可以直接解决,对于稍微复杂的,需要通过调试来解决。
程序是很容易出错的。程序错误被称为bug,查找bug的过程称为调试(debugging)。我们在第1章中已经介绍过一个很简单的调试示例。
语法错误:
在生活中有时会碰到这样的情况,你本应买今天去某地的火车票,已经买好了,但当进站检票时,系统告诉你票不是今天的,这时你才发现购买车票时输错了日期。
程序中这种错误比生活中出现的次数多很多,称为语法错误(syntax errors)。Python程序在语法正确的情况下才能运行,否则解释器会显示一条错误信息。语法指的是程序的结构和此结构的规则。比如第1章的('Hello,world!'),括号中的单引号是成对的,执行时才能正确执行。如果输入('Hello,world!)或(Hello,world!')就会报错,这属于语法错误。
我们在阅读文章或听人讲话时,可以容忍大多数语法错误,不过Python并不如此宽容。程序中只要出现一处语法错误,Python就会显示错误信息并退出,从而无法通过编译。就如我们进站,一旦票不满足进站要求,就无法进入一样。
在编程生涯的开始阶段,可能每踏出一步都会碰到大量语法方面的错误,随着经验的增加,犯错会减少,踩过坑后,后面遇到类似的坑就能快速应对了。
运行错误:
我们可能在奔跑的交通工具内愉悦地欣赏着远途的风景,但此时交通工具突然慢慢停下来了,并且司机对大家宣布说,交通工具抛锚了。例如,出现轮胎破损、没油了、发动机坏了、撞车事故等。
在Python中经常会遇到类似的错误,称之为运行时错误(runtime errors)。
即使是看起来完美无缺的程序,在运行的过程中也会出现错误。有人说,计算机不是善于精确计算吗?确实如此。不过错的不是计算机,而是我们人类。计算机说到底是人类设计的,是我们所用的工具,和电视机、汽车从本质上来说是一样的。鉴于现在计算机软硬件的理论水平、工业制造水平、使用者的水平等一些内在、外在的因素,出现错误并不稀奇,且程序越复杂,出现异常的概率越大。异常的种类很多,如内存用尽、除数为零的除法等都可能导致异常。Python为了把错误的影响降至最低,提供了专门的异常处理语句。
运行时错误一般在代码量偏多时才容易遇到。
语义错误:
经常乘坐交通工具,难免有乘错车的情况出现,比如你本应该乘坐801路车,却坐上了802路车,结果到达了不同的地方。
在Python中经常会发生类似的问题,此类问题称为语义错误(semantic errors)。
程序即使有语义错误,也能正常运行,不会产生任何错误信息,但得到的结果和我们预料的不一致。发生这种错误一般是我们对语句的运行机制了解得不够透彻,自以为它应该如此运行,实际上却不是这样。还有可能是你解决问题的思路本身就是错的,写的程序当然是错的。
查找语义错误并不像我们坐错了车那么容易,它可能需要你根据结果进行推理,不过推理的过程没有那么简单易行,需要查看程序输出,并尝试弄明白到底做了什么。