语言设计的相关知识

    一、与程序设计语言有关的人
    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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值