程序设计语言概述
程序设计语言是为了书写计算机程序而人为设计的符号语言,用于对计算过程进行描述、组织和推导。
程序设计语言的基本概念
低级语言和高级语言
计算机硬件只能识别由 0
、1
组成的机器指令序列,即机器指令程序,因此机器指令是最基本的计算机语言。
由于机器指令是特定的计算机系统所固有的、面向机器的语言,所以用机器语言进行程序设计时效率很低,程序的可读性很差,也难以修改和维护。因此,人们就用容易记忆的符号代替 0
、1
序列来表示机器指令,例如,用 ADD
表示加法、用 SUB
表示减法等。
像 ADD
、SUB
这样用符号表示的指令称为汇编指令,汇编指令的集合被称为汇编语言。汇编语言与机器语言十分接近,其书写格式在很大程度上取决于特定计算机的机器指令,因此它仍然是一种面向机器的语言,人们称机器语言和汇编语言为低级语言。
在此基础上,人们开发了功能更强、抽象级别更高的语言以支持程序设计,于是就产生了面向各类应用的程序设计语言,称为高级语言。常见的有 Java、 C、 C++、 PHP、 Python、Delphi、PASCAL 等。这类语言与人们使用的自然语言比较接近,提高了程序设计的效率。
编译程序和解释程序
计算机只能理解由 0
、1
序列构成的机器语言,因此高级程序设计语言需要翻译,担负这一任务的程序称为 “语言处理程序”。语言之间的翻译形式有多种,基本方式为汇编、解释和编译。
用某种高级语言或汇编语言编写的程序称为源程序,源程序不能直接在计算机上执行。
- 如果源程序是用汇编语言编写的,则需要一个汇编程序将其翻译成目标程序后才能运行。
- 如果源程序是用某种高级语言编写的,则需要对应的解释程序或编译程序对其进行翻译,然后才能运行。
解释程序也称为解释器,它直接解释执行源程序或者将源程序翻译成某种中间代码后再加以执行;编译程序也称为编译器,它是将源程序翻译成目标程序,然后在计算机上运行目标程序。这两种语言处理程序的根本区别是:
- 在编译方式下,机器上运行的是与源程序等价的目标程序,源程序和编译程序都不再参与目标程序的执行过程。
- 在解释方式下,解释程序和源程序 (或源程序的某种中间代码) 要参与到程序的运行过程中,运行程序的控制权在解释程序。
程序设计语言的定义
程序设计语言的定义涉及语法、语义和语用等方面。
语法
语法是指由程序设计语言的基本符号组成程序中的各个语法成分 (包括程序) 的一组规则。其中由基本字符构成的符号 (单词) 书写规则称为词法规则,由符号构成语法成分的规则称为语法规则。
语义
语义是程序设计语言中按语法规则构成的各个语法成分的含义,可分为静态语义和动态语义。静态语义指编译时可以确定的语法成分的含义,而运行时刻才能确定的含义是动态语义。
一个程序的执行效果说明了该程序的语义,它取决于构成程序的各个组成部分的语义。
语用
语用表示了构成语言的各个记号和使用者的关系,涉及符号的来源、使用和影响。
程序设计语言的分类
程序设计语言的分类没有统一的标准,这里根据设计程序的方法将程序语言大致分为:命令式和结构化程序设计语言、面向对象的程序设计语言、函数式程序设计语言和逻辑型程序设计语言。
命令式和结构化程序设计语言
命令式语言是基于动作的语言,在这种语言中,计算被看成是动作的序列。而通常所称的结构化程序设计语言属于命令式语言类,其结构特性主要反映在以下几个方面:
- 用自顶向下逐步精化的方法编程
- 按模块组织的方法编程
- 程序只包含顺序、判定 (分支) 及循环构造,而且每种构造只允许单入口和单出口
结构化程序的结构简单清晰、模块化强,描述方式接近人们习惯的推理式思维方式,因此可读性强,在软件重用性、软件维护等方面都有所进步,在大型软件开发中曾发挥过重要的作用。
C、PASCAL 等都是典型的结构化程序设计语言。
面向对象的程序设计语言
程序设计语言的演化从最开始的机器语言到汇编语言到各种结构化高级语言,最后到支持面向对象技术的面向对象语言,反映的就是一条抽象机制不断提高的演化道路。
C++、Java 和 Smalltalk 是面向对象程序设计语言的代表,它们都必须支持新的程序设计技术,如数据隐藏、数据抽象、用户定义类型、继承和多态等。
函数式程序设计语言
函数式语言是一类以 λ 演算 (lambda calculus) 为基础的语言,其基本概念来自于 LISP 语言。
函数是一种对应规则 (映射),它使定义域的每个元素和值域中唯一的元素相对应。由此可见,函数可以看成是一种程序,其输入就是定义域中的某个元素,其输出就是输入的某个元素映射在值域中唯一的元素。函数也可以将输入组合起来产生一个规则,在组合过程中可以使用其他函数或该函数本身。这种用函数和表达式建立程序的方法就是函数式程序设计。
函数式程序设计语言的优点之一就是对表达式中出现的任何函数都可以用其他函数来代替,只要这些函数调用产生相同的值。
常见的函数式语言有 Haskell、Scala、Scheme、APL 等。
逻辑型程序设计语言
逻辑型语言是一类以形式逻辑为基础的语言,其代表是建立在关系理论和一阶谓词理论基础上的 PROLOG。PROLOG 代表 Programming in Logic。PROLOG 程序是一系列事实、数据对象或事实间的具体关系和规则的集合。用户通过输入操作来执行程序。
程序设计语言的基本成分
程序设计语言的基本成分包括数据、运算、控制和传输等。
程序设计语言的数据成分
程序设计语言的数据成分指一种程序设计语言的数据类型。
- 数据对象总是对应着应用系统中某些有意义的东西,数据表示则指明了程序中值的组织形式。
- 数据类型用于代表数据对象,还用于在基础机器中完成对值的布局,同时还可用于检查表达式中对运算的应用是否正确。
数据是程序操作的对象,具有存储类别、类型、名称、作用域和生存期等属性,在使用时要为它分配内存空间。
- 数据名称由用户通过标识符命名,标识符是由字母、数字和下划线 “_” 组成的标记;
- 类型说明数据占用内存的大小和存放形式;
- 存储类别说明数据在内存中的位置和生存期;
- 作用域则说明可以使用数据的代码范围;
- 生存期说明数据占用内存的时间特点。
从不同角度可将数据进行不同的划分。
常量和变量
按照程序运行时数据的值能否改变,将数据分为常量和变量。
程序中的数据对象可以具有左值和 (或) 右值,左值指存储单元 (或地址、容器),右值是值 (或内容)。
- 变量具有左值和右值,在程序运行过程中其右值可以改变;
- 常量只有右值,在程序运行过程中其右值不能改变。
全局量和局部量
数据按在程序代码中的作用范围 (作用域) 可分为全局量和局部量。
一般情况下,全局变量的作用域为整个文件或程序,系统为全局变量分配的存储空间在程序运行的过程中是不改变的,局部变量的作用域为定义它的函数或语句块,为局部变量分配的存储单元是动态改变的。
数据类型
按照数据组织形式的不同可将数据分为基本类型、用户定义类型、构造类型及其他类型。C(C++) 的数据类型如下。
- 基本类型:整型 (int)、字符型 (char)、实型 (float、 double) 和布尔类型 (bool)。
- 特殊类型:空类型 (void)。
- 用户定义类型:枚举类型 (enum)。
- 构造类型:数组、结构、联合。
- 指针类型:
type *
。 - 抽象数据类型:类类型 (class)。
其中,布尔类型和类类型由 C++ 语言提供。
程序设计语言的运算成分
程序设计语言的运算成分指明允许使用的运算符号及运算规则。
大多数高级程序设计语言的基本运算可以分成算术运算、关系运算和逻辑运算等,有些语言 (如 C、C++) 还提供位运算。运算符号的使用与数据类型密切相关。为了明确运算结果,运算符号要规定优先级和结合性,必要时还要使用圆括号。
程序设计语言的控制成分
程序设计语言的控制成分指明语言允许表述的控制结构,通过控制成分来构造程序中的控制逻辑。
可计算问题的程序都可以用顺序、选择和循环这 3 种控制结构来描述。
顺序结构
顺序结构用来表示一个计算操作序列。计算过程从所描述的第一个操作开始,按顺序依次执行后续的操作,直到序列的最后一个操作。在顺序结构内也可以包含其他控制结构。
选择结构
选择结构提供了在两种或多种分支中选择其中一个的逻辑。基本的选择结构是指定一个条件 P,然后根据条件的成立与否决定控制流计算 A 还是计算 B,从两个分支中选择一个执行。
// 选择结构
if (P) {
// 分支 A
} else {
// 分支 B
}
选择结构中的计算 A 或计算 B 还可以包含顺序、选择和循环结构。
程序设计语言中还通常提供简化了的选择结构,也就是没有计算 B 的分支结构。
// 选择结构 简化
if (P) {
// 分支 A
}
循环结构
循环结构描述了重复计算的过程,通常由三部分组成:初始化、循环体和循环条件,其中初始化部分有时在控制的逻辑结构中不进行显式的表示。
循环结构主要有两种形式:while 型循环结构和 do-while 型循环结构。
- while 型结构的逻辑含义是先判断条件 P,若成立,则执行循环体 A,然后再去判断循环条件,否则控制流就退出重复结构。
- do-while 型结构的逻辑含义是先执行循环体 A,再判断条件 P,若成立则继续执行 A,然后再判断条件 P,否则控制流就退出循环结构。
// 循环结构 while
while (P) {
// 循环体 A
}
// 循环结构 do-while
do {
// 循环体 A
} while (P);
程序设计语言的传输成分
程序设计语言的传输成分指明语言允许的数据传输方式,如赋值处理、数据的输入和输出等。