目录
对于计算机而言,cpu只能识别机器语言(机器码,二进制序列),执行程序的过程就是硬盘上的程序被选中时,将此程程序装入到内存中,cpu再到内存中陆续取出每一条指令并执行。装入内存中的每一条指令就只能是机器码。所以不管使用什么样的计算机编程语言编写的程序,最终在执行程序前(装入内存前)都得将程序转换成机器码表示。
演化
机器语言
在计算机发展早期,唯一的程序设计语言就是机器语言,机器语言话由(“0”, “1”)二进制序列组成。机器语言是计算机硬件唯一能理解并直接运行的语言,由两种状态的电子开关构成:关(0),开(1)。是二进制语言,属于低级语言。
计算机唯一识别的语言是机器语言。
以下是读两个整数并相加输出结果的机器语言。领略一下,总共需要11行二进制码。
优点:计算机可以直接执行、简洁、运算速度快等
缺点:
- 高度依赖计算机。如果使用不同的硬件,那么一台计算机的机器语言与另一台计算机的机器语言就不同。
- 用这种语言编写程序很乏味,全部是二进制表达,很难发现错误。
汇编语言
为了好记,用带符号或助记符的指令和地址代替二进制码而演变来的语言是符号语言。后来也被称为汇编语言。每一条机器指令都必须单独编码。
以下是读两个整数并相加输出结果的汇编语言。同样是11行代码,当相比上面的机器语言,人类更容易读写。
汇编语言大大提高了编程效率,单仍然需要程序员在使用的硬件上花费大部分精力。
汇编语言是面向机器的低级语言,不能被机器直接识别,需要编译,使用汇编程序将汇编语言翻译成机器语言。
高级语言
高级语言是为了进一步解决汇编语言的问题,具备可以移植到许多不同的计算机,使程序员不再大量关注计算机复杂的结构。高级语言为程序员提供了一种既接近于自然语言,又可以使用数学表达式,还相对独立于机器的编程语言。
高级语言是从人类的逻辑思维角度出发的计算机语言,不能被机器直接识别,需要转化翻译为机器语言,这个过程被称为编译或解释。如目前流行的Java,C,C++,C#,Pascal,Python等。
翻译
当今程序通常使用高级语言编写,为了在机器上运行,编写的程序需要被翻译成它要运行在其他的机器上的机器语言。高级语言程序被称为源程序。被翻译成机器语言程序称为目标程序。 有两种方式用于翻译:编译 和 解释。
- 编译:编译程序通常把整个源程序翻译成目标程序。
- 解释:解释器把源程序中的每一行翻译成目标程序中相应的行,并执行它的过程。目前解释发展为两种趋势:Java语言之前被有些程序使用的解释 和 Java使用的解释。
- 第一种解释方法:在Java语言之前的有些解释性语言使用的解释过层。源程序的每一样被翻译成被其使用的机器上的机器语言,该行机器语言立即执行。如果在翻译和执行中有任何错误,过程就显示消息,其余的过程被中止。程序需要改正,再次从头解释和执行。第一种方法被看成一种慢的过程,这时大多数语言使用编译而不是解释的原因。
- 第二种解释方法:Java引入了这种解释方式,Java语言能向任何计算机移植。为了取得可移植性,源程序到目标程序的翻译分成两步进行:编译和解释。Java源程序受限被编译,创建Java的字节代码,并不是机器码,是一种虚拟机的目标程序,该虚拟机称为Java或JVM。字节代码然后能被任何运行JVM模拟器的计算机编译或解释,也即是运行字节代码的计算机只需要JVM模拟器。
翻译过程
编译和解释都遵循下图显示的翻译过程
- 词法分析器:一个符号一个符号读取文件的中的源代码,创建源语言中的助记符表。例如,5个符号w、h、i、l、e被读入,组合起来就形成了助记符while。
- 语法分析器:分析一组助记符,找出指令。例如,将“index”、“=”、“25”这三个助记符组合成一个赋值语句 index=25。
- 语义分析器:检查语法分析器创建的句子,确保它们不含二义性。
- 代码生成器:将上面检查通过的语句指令转化为一组程序将要在其上运行的计算机的机器语言。
编程模式
计算机语言按照它们使用的解决问题的方法来分类。模式是计算机语言看待要解决问题的一种方式,计算机语言可分为4种模式:过程性(强制性)、面向对像、函数式和声说式。
过程式模式
我们把程序看成是操纵被动对象的主动主体。在这种世界观里,只有程序是主动主体,程序使用的所有数据或数据项是被动对象,被动对象的数据项存储在计算机的内存中,程序操控它们。为了操纵数据,程序发出动作,称为过程。
过程式开发语言代表:C、Pascal。
需要把过程与程序触发区分开。程序不定义过程,它只触发过程(程序仅由许多过程调用构成),过程必须已经存在。
这种模式的程序由三部分构成:对象构建部分、一组过程调用、每个过程的一组代码。有些过程在语言本身中已经被定义。通过组合这些代码,开发者可以建立新的过程。
下图显示了过程式程序的三个组成部分。在语言中也有额外的助记符来界定或组织调用。
书中的例子,程序调用一些已经定义好的文件处理过程去操纵一些文件。
面向对象模式
程序处理活动对象,对象只需要接收合适的外部刺激来执行其中的一个动作(对象的自有动作)。这种模式下,活动对象具备一些可以操纵自己属性的方法,这些方法被相同类型的对象共享,也被从这些对象继承的其他子对象共享。
面向对象式开发语言代表:C、Java、C#。
下图同样是实现程序操纵一组文件,与过程式不同的是,面向对象是通过刺激指定的对象,让其执行自己的方法来完成需求。
过程模式中的过程是独立的实体,面向对象模式中的方法是属于对象的。
- 封装:相同类型的对象需要一组方法,这些方法显示了这类对来自对象之外的刺激的反应,通过类(class)来创建这些方法,同时类中定义一些成员变量来保存每个对象的属性。
- 继承:一个对象能从另一个对象继承。例如一个human 类定义后,就可以定义 woman 和 man 并分别继承自 human,同时woman和man分别具有一些新特性。
- 多态:子类对象地址可以赋值给父类指针,在运行时,当这个父类指针调用父类和子类中都有的同名、同参数表的虚函数的语句时,根据此时指针所指向的对象是什么类型就调用真实的那种类型的方法。例如,上面的human,woman,man三个类在都定义逛街(GoShopping)这个方法,当父类指针指向的是woman,那么这个方法是买买买;如果父类指针指向的是man,那么这个方法是陪陪女朋友买买买。
函数式模式 和 说明是模式
这两者没有接触过,再此不表。
共同概念
标识符
对象的名称,每一个对象是存储在内存中的一个唯一的物理地址中,标识符就是这个物理地址的一个代表,只要给出数据的名字就可以让编译器去跟踪数据实际存放数据的物理地址。
数据类型
定义了一系列指及这些值的一系列操作
- 简单数据类型:是不能分解成更小数据类型的类型,整数、实数、字符、布尔类型。每种类型都预设了内存大小和在内存中的存储方法。
- 复合数据类型:是一组元素,数组和记录,数组中的每个元素类型相同,记录中的元素类型可以不同。
- 变量:变量是存储单元的名称,当定义了一个变量,就确定了变量的类型,则确定了在内存中的地址和内存分配的大小与存储方式。定义的变量则表明这个对应内存中的存储的值在程序运行过程中可以被程序修改。
- 字面值:是程序中使用的预定义的值,可以是任何基本类型和字符串的字面值,如:300、10.02、false、‘a’、“test” 等。
- 常量:与变量的区别就是在程序整个生命周期中一经定义就不能被修改。
- 输入输出:大多数程序语言使用一些预先定义好的函数完成输入输出。
- 表达式:一些列操作数和运算符简化后的一个单一数值。操作数接收一个运算符的动作。以下是三种运算符:
语句
每条语句都使程序执行一个响应动作,它被直接翻译成一条或多条计算机可执行的指令。
赋值语句:给变量赋值。
复合语句:一个包含0个或多个语句的代码单元(块),一般用一对花括号{} 围起来:
控制语句:与算法_三种结构 中的选择和循环一起理解。
三种循环的区别:
for循环、while循环都是先判断条件是否成立,成立才执行循环体(先判断后执行)。
do...while循环先执行一次循环体,然后判断条件是否成立,成立继续执行循环体(先执行后判断)。
for和while的区别:
条件控制语句所控制的自增变量,可能归属for循环的局部变量,for循环结束后,在for之后不能被访问。
条件控制语句所控制的自增变量,对于while循环来说不是局部变量,在while循环结束后,该变量还可以继续使用。
子程序:与算法_子算法 中的子算法一起理解。
局部变量:当子程序每次被调用时,子程序中的局部变量被创建,局部对象属于子程序。
参数:调用子程序的过程中,主程序使用的是实际参数,子程序中称为形式参数。
传值:调用时将实际参数的值赋给形势参数,这两个参数分别有自己的内存块,没有在同一个内存,所以是两个没有干系的参数。
传引用:调用时变量的内存地址被子程序内外共享,形势参数不再是子程序的局部变量。
返回值:子程序可以有一个或多个返回值。
凡是过往,即为序章