一、与程序设计语言有关的人
1. 语言的设计者。
2. 语言的实现者。
3. 语言的使用者。
二、历史上有重要影响的程序语言
1. 汇编语言
1948年,英国 David Wheeler (惠勒) 为剑桥大学发明的计算机 EDSAC 写了他称之为起始指令的30行指令。这就是汇编语言的开端。
2. Fortran 语言
意为 FORmula TRANslation。由 IBM 公司 Backus 领导的团队设计,于 1957 年推出的第一个的高级语言,主要用于科学计算。引入了高级语言的许多概念,如变量、赋值、数组、无条件(goto)语句、条件语句、循环语句、读语句、写语句、子程序等。
3. ALGOL 语言
意为 Algorithm Language。由德国和美国的科学家设计,于1960年推出 ALGOL 60。首次用巴科斯-诺尔范式(BNF)描述。引入了程序块 (Block)、递归过程、动态数组等新概念。ALGOL 在欧洲、中国等国家得到了广泛的应用。
4. COBOL 语言
由女程序员 Grace Hopper (1906-1992) 博士领导的一个工作委员会,研制出的第一个的商用编程语言。引入了文件、数据描述、变体记录等概念。该语言的语句近似于英语句子。Grace Hopper 为大型数字计算机 Mark-I、Mark-II、Mark-III 写出了大量程序,写出了世界上第一个编译程序 A-0。
5. LISP 语言
由麻省理工学院 John McCarchy 于1960年设计和实现的人工智能语言,是第一个的函数式语言。采用统一的数据结构——表(list),程序作为数据的一部分。
6. Pascal 语言
由美籍瑞士人 Niklaus Wirth 设计、并于1970年推出的语言。支持记录和指针的动态数据分配(new),支持嵌套(局部)过程和函数。在多达20年的时间里成为大学里广泛使用的教学语言。
7. C 语言
美国 Bell 实验室的 Richie 于1973年发明。直至今天,仍广泛用于系统编程、应用编程和教学,生机勃勃。在编程中大量使用指针,既灵活、高效,也是许多难以查出的错误的来源。
8. Ada 语言
表现能力很强的通用程序设计语言,它是美国国防部为克服软件开发危机而招标,耗费巨资,历时近20年研制成功。以严谨、高度安全为目标,实现了软件工程学的许多思想。多用于军用软件开发。
9. C++
基于 C 语言,引入了面向对象。功能强大,支持泛型,有一个庞大的库。语法晦涩。
10. Java 语言
由美国 Sun 公司的 James Gosling 领导的小组设计,于1995年推出。其面向对象的特性,类似于C++语言。也有一个庞大的库。采用垃圾回收、数组下标越界检查,取消了显式的指针,程序安全性高。采用独立于平台的Java虚拟机,目标程序的执行速度比C/C++慢。多用于大型项目开发。
三、数据类型
1. 基本类型
C:
void,
(unsigned )char, (unsigned )int, (unsigned )long, enum,
float, double, long double。
Pascal:
integer, real, char, boolean。
Ada:
Boolear, Character, Integer, Float。
Java:
boolean, char, byte, short, int, long, float, double。
2. 结构类型
C:
struct {
char id[20];
int age;
} person;
Pascal:
person: record
id: array[1..20] of char;
age: integer;
end;
Ada:
type Coordinate is
record
x: INTEGER range 0..1023;
y: CHARACTER;
end;
3. 数组
Pascal:
var a: array[1..50] of char;
C:
char a[50];
4. 指针和递归定义
二叉树的定义:
C:
typedef Node * Tree;
struct Node {
int data;
Tree left, right;
};
Pascal:
type
Tree = ^Node;
Node = record
data: int;
left, right: Tree;
end;
Ada:
type Node;
type Tree is access Node;
type Node is
record
data: INTEGER;
left, right: Tree;
end;
5. 枚举和集合
Pascal:
type Color = (red, green, blue, black, white);
var set of Color;
C:
typedef enum {red, green, blue, black, white} Color;
Ada:
type BOOLEAN is (FALSE, TRUE);
6. 子界
Ada:
type Score is range 0..100;
Pascal:
type Score = 0..100;
C:
无。
四、类型检测
1. 类型的兼容性 (compatible) 检测
表达式中的运算对象,赋值中右边和左边,函数调用中实参和形参,编译时要检查类型是否兼容。
如在 C 中,
int a = 100, x;
double b = 0.618;
char c = 'A';
char * st = "Hello.";
x = a + b + c; // 合法
a + st // 不合法
但在 JavaScript 中,数和字符串相加是合法的。
类型检测是语言可靠性中的一个重要因素。编译时的类型检测要比运行时的类型检测更为理想,因为运行时的类型检测代价很高。程序中的错误发现得越早,改正错误的代价就越低。
现代语言还具有及时改正运行时错误,即异常处理的能力。
2. 类型等价
有两类等价:
1) 名字等价:具有相同的类型名者,为等价。
2) 结构等价:具有相同的结构者,为等价。
C 语言规定: 1) struct 和 union 采用名字等价。2) 数组和指针采用结构等价。
示例:
1)
#include <stdio.h>
struct Point {
double x, y;
};
struct Pos {
double x, y;
};
int main() {
struct Point p = {1.2, -2};
struct Pos q;
q = p; //出错:struct 不采用结构等价
printf("q = {%g, %g}\n", q.x, q.y);
}
2)
#include <stdio.h>
struct Point {
double x, y;
};
typedef struct Point Complex;
int main() {
struct Point p = {1.2, -2};
Complex r;
r = p; //合法:struct 采用名字等价
printf("r = {%g, %g}\n", r.x, r.y);
}
3)
typedef struct {
char *id;
int sym;
} Keyword;
Keyword keywords[] = {
{ "int", INT },
{ "double", DOUBLE },
{ "if", IF },
{ "else", ELSE },
{ "while", WHILE },
{ "read", READ },
{ "print", PRINT },
{ "return", RETURN },
{ NULL, 0 }
};
int keyword_lookup(char *id) {
Keyword * q = keywords; // 数组和指针采用结构等价
while (q->id != NULL && strcmp(q->id, id) != 0)
q++;
return q->sym;
}
五、语言的种类
1. 命令式语言 (Imperative Language)
编程以赋值为基础,通过值的改变实现计算,是对图灵机理论的实现。冯·诺依曼提出了实现命令式编程机器的体系结构。
现实中广泛应用的语言大多数属于命令式语言,从 FORTRAN、Algol、Pascal、C,到 C++、Java 等都是。因为,今天的计算机仍属于冯·诺依曼架构,其机器语言以值的改变为特征,因此命令式编程语言容易编译为机器语言,实现高效的计算。
2. 函数式语言 (Functional Language)
实现了一种编程模型,将计算机运算看做是数学中函数的计算,避免了状态和数据 (变量) 的可变性。以阿隆左·丘奇的 lambda 演算为基础,强调无副作用、惰性求值、局部套用等理念。
1958年,MIT 教授 John McCarthy 设计了第一个函数式语言 Lisp,用于符号数据处理,如微积分运算。之后出现了不同纯度的函数式语言:ML,Scheme,Haskell,JavaScript,Erlang,等。
纯的函数式语言中,函数用于几乎一切的计算,包括加减乘除,并取代变量。变量是表达式的别名,只能赋值一次,值不能更改。函数调用无副作用,天生适用于并行编程。弥补了命令式语言的缺陷:并行编程非常复杂,依赖于信号量、锁,程序员不堪重负。
六、语言的定义和标准
1. 语言定义
编程语言由语言参考手册定义。其中语法由文法规则或语法图定义,语义则由自然语言描述。
2. 语言标准
具有世界范围流行的语言,国际标准化组织为其制定的标准。如 C89、C99等。
七、语言设计的目标
1. 简单性
简单性强的语言可读性也强,编写程序也容易。如 SQL、C 可读性强,C++ 可读性不强。
2. 表达性
语言的表达能力。
3. 正交性
正交 (orthogonal) 本是几何上的一个概念,表示垂直相交。一组两两正交的正交向量组撑起了一个线性空间,如二维空间、三维空间。空间中的任何向量都可以由这一组正交向量的线性组合得出。
在编程语言领域,正交表示基本结构之间互相独立和良好隔离,并且能组合出一个 "功能空间"。在这组正交的基本结构中,任何一个不能由其它组合得到,即缺一不可。
一组较少数量的基本结构,以及一套相互一致的结构组合(即正交性),比起提供大量的基本结构,要优越得多。
正交性好的语言,语言结构简洁,语句和子句尽量少,语句的组合实现尽可能强大的功能。
SQL 语言的正交性有口皆碑,C 语言的正交性也不错。C++ 的正交性很糟糕。
4. 精确性
不出现歧义性。
5. 可靠性
如 Ada 可靠、严谨。Java 是安全的。C 的定位是简单性、表达性和速度,可靠性在语言设计上稍欠,而由程序员保证。
八、代码优化
1. 指令选择
像 x86、x86-64,指令有上千条之多,选择哪些指令,需要在效率和复杂之间平衡。
2. 寄存器分配
局部变量、临时变量尽量存放在寄存器中。但寄存器是宝贵资源,哪些变量分配寄存器,哪些溢出到内存,是研究的大热门。
3. 删除多余指令
4. 删除死代码
5. 常量折叠
编译时计算。x = 100 + 200 + y; => x = 300 + y;