更新说明
/


1. 程序设计语言的基本概念

计算机硬件只能识别由 0、1 组成的机器指令序列,即机器指令程序,因此机器指令是最基本的计算机语言。由于机器指令是特定的计算机系统所固有的、面向机器的语言,所以用机器语言进行程序设计时效率很低,程序的可读性很差,也难以修改和维护

汇编语言与机器语言十分接近,其书写格式在很大程度上取决于特定计算机的机器指令,因此它仍然是一种面向机器的语言,人们称机器语言和汇编语言为低级语言

在此基础上,人们开发了功能更强、抽象级别更高的语言以支持程序设计,于是就产生了面向各类应用的程序设计语言,称为高级语言。

计算机只能理解由0、1序列构成的机器语言,因此高级程序设计语言需要翻译,担负这一任务的程序称为“语言处理程序”语言之间的翻译形式有多种,基本方式为汇编、解释和编译。用某种高级语言或汇编语言编写的程序称为源程序,源程序不能直接在计算机上执行。如果源程序是用汇编语言编写的,则需要一个汇编程序将其翻译成目标程序后才能执行。如果源程序是用某种高级语言编写的,则需要对应的解释程序或编译程序对其进行翻译,然后在机器上运行。

解释程序也称为解释器,它或者直接解释执行源程序,或者将源程序翻译成某种中间代码后再加以执行;编译程序(编译器)则是将源程序翻译成目标语言程序,然后在计算机上运行目标程序。
这两种语言处理程序的根本区别是:解释源程序时不生成独立的目标程序,编译器则将源程序翻译成独立保存的目标程序

语法是指由程序设计语言的基本符号组成程序中的各个语法成分(包括程序)的一组规则。

语义是程序设计语言中按语法规则构成的各个语法成分的含义,可分为静态语义和动态语义。

语用表示了构成语言的各个记号和使用者的关系,涉及符号的来源、使用和影响。

语境是指理解和实现程序设计语言的环境,包括编译环境和运行环境。

种类:
Fortran (Formula Translation) 是第一个被广泛用来进行科学和工程计算的高级语言。
PASCAL 是一种过程式、结构化程序设计语言。曾经非常流行。1985 年发布了Object Pascal。
C 语言是 20 世纪 70 年代初发展起来的一种通用程序设计语言。它兼顾了高级语言和汇编语言的特点,提供了一个丰富的运算符集合以及比较紧凑的语句格式。由于 c 提供了髙效的执行语句并且允许程序员直接访问操作系统和底层硬件,因此在系统级应用和实时处理应用开发中成为主要语言
C++比 C 多了封装和抽象,增加的类机制使 C++成为一种面向对象的程序设计语言。C# (C Sharp)一种面向对象的、运行于.NET Framework 的高级程序设计语言。
Java 初始用途是开发网络浏览器的小应用程序,但是作为一种通用的程序设计语言,Java得到非常广泛的应用。Java保留了C++ 的基本语法、类和继承等概念,删掉了 C++中一些不好的特征,因此与 C++相比,Java 更简单,其语法和语义更合理。
Python是一种面向对象的解释型程序设计语言,可以用于编写独立程序、快速脚本和复杂应用的原型。Python也是一种脚本语言, 它支持对操作系统的底层访问,也可以将Python源程序翻译成字节码在 Python 虚拟机上运行。
JavaScript 是一种脚本语言,被广泛用于 Web 应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。

命令式和结构化程序设计语言。命令式语言是基于动作的语言,在这种语言中,计算被看成是动作的序列。命令式语言族开始于Fortran, PASCAL 和 C 语言都可以体现命令式程序设计的关键思想。

面向对象的程序设计语言。程序设计语言的演化从最开始的机器语言到汇编语言到各种结构化高级语言,最后到支持面向对象技术的面向对象语言,反映的就是一条抽象机制不断提高的演化道路。C++、Java 和 Smalltalk 是面向对象程序设计语言的代表,它们都必须支持新的程序设计技术,如数据隐藏、数据抽象、用户定义类型、继承和多态等。

函数式程序设计语言。基本概念来自于LISP, 这是一个在 1958 年为了人工智能应用而设计的语言。函数是一种对应规则(映射), 它使定义域的每个元素和值域中唯一的元素相对应。

逻辑型程序设计语言。逻辑型语言是一类以形式逻辑为基础的语言,其代表是建立在关系理论和一阶谓词理论基础上的 PROLOG。

【真题】 A 是一种函数式编程语言。
A.Lisp B.Prolog C.Python D.Java/C++


2. 程序设计语言的基本成分

程序设计语言的基本成分包括数据、运算、控制和传输等。

数据是程序操作的对象,具有存储类别、类型、名称、作用域和生存期等属性,在使用时要为它分配内存空间。数据名称由用户通过标识符命名,标识符是由字母、数字和下划线组成的标记;类型说明数据占用内存的大小和存放形式;存储类别说明数据在内存中的位置和生存期;作用域则说明可以使用数据的代码范围;生存期说明数据占用内存的时间特点。从不同角度可将数据进行不同的划分。

数据

  1. 常量和变量

按照程序运行时数据的值能否改变,将数据分为常量和变量。程序中的数据对象可以具有左值和(或)右值,左值指存储单元(或地址、容器),右值是值(或内容h 变量具有左值和右值,在程序运行过程中其右值可以改变;常量只有右值,在程序运行过程中其右值不能改变。

  1. 全局量和局部量

数据按在程序代码中的作用范围(作用域)可分为全局量和局部量。一般情况下,全局变量的作用域为整个文件或程序,系统为全局变量分配的存储空间在程序运行的过程中是不改变的,局部变量的作用域为定义它的函数或语句块,为局部变量分配的存储单元是动态改变的。
图片.png
图片.png

  1. 数据类型

按照数据组织形式的不同可将数据分为基本类型、用户定义类型、构造类型及其他类型。C (C++) 的数据类型如下。
(1) 基本类型:整型(int)、字符型(char)、实型(float、double) 和布尔类型(bool)。
(2) 特殊类型:空类型(void)。
(3) 用户定义类型:枚举类型(enum)
(4) 构造类型:数组、结构、联合。(5 ) 指针类型:type *
(6) 抽象数据类型:类 类型。
其中,布尔类型和类类型由 C++语言提供。
【真题】以下关于程序设计语言的叙述中,错误的是 C 。
A. 程序设计语言的基本成分包括数据、运算、控制和传输等
B. 高级程序设计语言不依赖于具体的机器硬件
C. 程序中局部变量的值在运行时不能改变
D. 程序中常量的值在运行时不能改变

控制

  1. 顺序结构

顺序结构用来表示一个计算操作序列。计算过程从所描述的第一个操作开始,按顺序依次执行后续的操作,直到序列的最后一个操作。在顺序结构内也可以包含其他控制结构。

  1. 选择结构

选择结构提供了在两种或多种分支中选择其中一个的逻辑。基本的选择结构是指定一个条件P, 然后根据条件的成立与否决定控制流计算 A 还是计算B,从两个分支中选择一个执行。选择结构中的计算 A 或计算 B 还可以包含顺序、选择和重复结构。程序设计语言中还通常提供简化了的选择结构,也就是没有计算 B 的分支结构。

  1. 循环结构

循环结构描述了重复计算的过程,通常由三部分组成:初始化、循环体和循环条件,其中初始化部分有时在控制的逻辑结构中不进行显式的表示。循环结构主要有两种形式:while和do-while型
图1.png
图2.png

传输

程序设计语言的传输成分指明语言允许的数据传输方式,如赋值处理、数据的输入和输出等。
C 程序由一个或多个函数组成,每个函数都有一个名字,其中有且仅有一个名字为 main 的函数作为程序运行时的起点。函数是程序模块的主要成分,它是一段具有独立功能的程序。
函数的使用涉及 3 个概念:函数定义、函数声明和函数调用。

  1. 函数定义

函数的定义包括两部分:函数首部和函数体。函数的定义描述了函数做什么和怎么做。函数定义的一般形式为

  1. 函数声明

函数应该先声明后引用。如果程序中对一个函数的调用在该函数的定义之前进行,则应该在调用前对被调用函数进行声明。函数原型用于声明函数。函数声明的一般形式为:

  1. 函数调用

当在一个函数(称为调用函数)中需要使用另一个函数(称为被调用函数)实现的功能时,便以名字进行调用,称为函数调用。在使用一个函数时,只要知道如何调用就可以了,并不需要关心被调用函数的内部实现。因此,调用函数需要知道被调用函数的名字、返回值和需要向被调函数传递的参数(个数、类型、顺序)等信息
图片.png
图片.png
2.png


3. 汇编程序基本原理

汇编语言是为特定的计算机设计的面向机器的符号化的程序设计语言。用汇编语言编写的程序称为汇编语言源程序。因为计算机不能直接识别和运行符号语言程序,所以要用专门的翻译程序—汇编程序进行翻译。用汇编语言编写程序要遵循所用语言的规范和约定。汇编语言源程序由若干条语句组成,其中可以有三类语句:指令语句、伪指令语句和宏指令语句

  1. 指令语句。指令语句又称为机器指令语句,将其汇编后能产生相应的机器代码,这些代码能被CPU 直接识别并执行相应的操作。基本的指令有ADD、SUB 和AND 等,书写指令语句时必须遵循指令的格式要求。指令语句可分为传送指令、算术运算指令、逻辑运算指令、移位指令、转移指令和处理机控制指令等类型。
  2. 伪指令语句。伪指令语句指示汇编程序在汇编源程序时完成某些工作,例如为变量分配存储单元地址,给某个符号赋一个值等。伪指令语句与指令语句的区别是:伪指令语句经汇编后不产生机器代码,而指令语句经汇编后要产生相应的机器代码。另外,伪指令语句所指示的操作是在源程序被汇编时完成的,而指令语句的操作必须在程序运行时完成
  3. 宏指令语句。在汇编语言中,还允许用户将多次重复使用的程序段定义为宏。宏的定义必须按照相应的规定进行,每个宏都有相应的宏名。


汇编程序的基本工作:
包括将每一条可执行汇编语句转换成对应的机器指令;处理源程序中出现的伪指令。由于汇编指令中形成操作数地址的部分可能出现后面才会定义的符号,所以汇编程序一般需要两次扫描源程序才能完成翻译过程。

第一次扫描的主要工作是定义符号的值并创建一个符号表ST,ST 记录了汇编时所遇到的符号的值。另外,有一个固定的机器指令表M0T1,其中记录了每条机器指令的记忆码和指令的长度。在汇编程序翻译源程序的过程中,为了计算各汇编语句标号的地址, 需要设立一个位置计数器或单元地址计数器LC (Location Counter), 其初值一般为 0。在扫描源程序时,每处理完一条机器指令或与存储分配有关的伪指令(如定义常数语句、定义储存语句),LC 的值就增加相应的长度。这样,在汇编过程中,LC 的内容就是下一条被汇编的指令的偏移地址。若正在汇编的语句是有标号的,则该标号的值就取 LC 的当前值。

第二次扫描的任务是产生目标程序。除了使用前一次扫描所生成的符号表 ST 外,还要使用机器指令表 MOT2,该表中的元素有机器指令助记符、机器指令的二进制操作码(Binary-code)、格式(Type) 和长度(Length)。此外,还要设立一个伪指令表 POT2, 供第二次扫描时使用。POT2 的每一元素仍有两个域:伪指令记忆码和相应的子程序入口。与第一次扫描的不同之处是:在第二次扫描中,伪指令有着完全不同的处理。:一是把机器指令助记符转换成二进制机器指令操作码,这可通过查找 M0T2表来实现;二是求出操作数区各操作数的值(用二进制表示)。在此基础上,就可以装配出用 二进制代码表示的机器指令。


4. 编译程序基本原理

编译程序的功能是把某高级语言书写的源程序翻译成与之等价的目标程序(汇编语言或机器语言)。编译程序的工作过程可以分为 6 个阶段,如图所示,在实际的编译器中可能会将其中的某些阶段结合在一起进行处理。
image.png

  1. 词法分析

源程序可以简单地被看成是一个多行的字符串。词法分析阶段是编译过程的第一个阶段,这个阶段的任务是对源程序从前到后(从左到右)逐个字符地扫描,从中识别出一个个“单词”符号。“单词”符号是程序设计语言的基本语法单位,如关键字(或称保留字)、标识符、常数、运算符和分隔符(如标点符号、左右括号)等。词法分析程序输出的“单词”常以二元组的方式输出,即单词种别和单词自身的值。

  1. 语法分析

语法分析的任务是在词法分析的基础上,根据语言的语法规则将单词符号序列分解成各类语法单位,如“表达式”“语句”和“程序”等。

  1. 语义分析

语义分析阶段分析各语法结构的含义,检査源程序是否包含静态语义错误,并收集类型信息供后面的代码生成阶段使用。只有语法和语义都正确的源程序才能翻译成正确的目标代码。语义分析的一个主要工作是进行类型分析和检查。程序设计语言中的一个数据类型一般包两个方面的内容:类型的载体及其上的运算。例如,整除取余运算符只能对整型数据进行运算,若其运算对象中有浮点数就认为是类型不匹配的错误

  1. 中间代码生成

中间代码生成阶段的工作是根据语义分析的输出生成中间代码。“中间代码”是一种简单 且含义明确的记号系统,可以有若千种形式。

  1. 代码优化

由于编译器将源程序翻译成中间代码的工作是机械的、按固定模式进行的,因此,生成的中间代码往往在时间上和空间上有较大的浪费。当需要生成高效的目标代码时,必须进行优化。

  1. 符号表管理

符号表的作用是记录源程序中各个符号的必要信息,以辅助语义的正确性检査和代码生成,在编译过程中需要对符号表进行快速有效地査找、插入、修改和删除等操作。

  1. 出错处理

用户编写的源程序不可避免地会有一些错误,这些错误大致可分为静态错误和动态错误。动态错误也称动态语义错误,它们发生在程序运行时,例如变量取零时做除数、引用数组元素下标错误等。静态错误是指编译阶段发现的程序错误,可分为语法错误和静态语义错误。


5. 解释程序基本原理

解释程序是另一种语言处理程序,在词法、语法和语义分析方面与编译程序的工作原理基本相同,但是在运行用户程序时,它直接执行源程序或源程序的中间表示形式。因此,解释程序不产生源程序的目标程序,这是它和编译程序的主要区别。
解释程序通常可以分成两部分:第一部分是分析部分,包括通常的词法分析、语法分析和语义分析程序,经语义分析后把源程序翻译成中间代码,常用的中间代码有:语法树,后缀式(逆波兰式),三地址代码。第二部分是解释部分,用来对第一部分产生的中间代码进行解释执行。

编译与解释的比较:
(1) 效率。编译比解释方式可能取得更高的效率。—般情况下,在解释方式下运行程序时,解释程序可能需要反复扫描源程序。例如,每一次引用变量都要进行类型检查,甚至需要重新进行存储分配,从而降低了程序的运行速度。在空间上,以解释方式运行程序需要更多的内存,因为系统不但需要为用户程序分配运行空间,而且要为解释程序及其支撑系统分配空间。
(2) 灵活性。由于解释程序需要反复检查源程序,这也使得解释方式能够比编译方式更灵活。当解释器直接运行源程序时,“在运行中”修改程序就成为可能,例如增加语句或者修改错误等。另外,当解释器直接在源程序上工作时,它可以对错误进行更精确地定位。
(3) 可移植性。解释器一般也是用某种程序设计语言编写的,因此只要对解释器进行重新编译,就可以使解释器运行在不同的环境中。

【真题】将高级语言源程序翻译为可在计算机上执行的形式有多种不同的方式,其中 C 。
A. 编译方式和解释方式都生成逻辑上与源程序等价的目标程序
B. 编译方式和解释方式都不生成逻辑上与源程序等价的目标程序
C. 编译方式生成逻辑上与源程序等价的目标程序,解释方式不生成
D. 解释方式生成逻辑上与源程序等价的目标程序,编译方式不生成

【真题】以下关于高级程序设计语言实现的编译和解释方式的叙述中,正确的是 A 。
A. 编译程序不参与用户程序的运行控制,而解释程序则参与
B. 编译程序可以用高级语言编写,而解释程序只能用汇编语言编写
C. 编译方式处理源程序时不进行优化,而解释方式则进行优化
D. 编译方式不生成源程序的目标程序,而解释方式则生成