06 程序设计语言知识

Posted on Wed, 25 Dec 2024 16:44:11 +0800 by LiangMingJian


1.程序设计语言的分类

1.1 按语言级别分类

  • 低级语言:包括字位码(唯一能被机器直接理解的语言),机器语言,汇编语言,特点高效,但使用复杂,易出错。
  • 高级语言:能让程序设计不再依赖于平台,允许程序员在不同平台上设计软件。高级语言不被机器直接执行,而是会进行编译,在编译成机器语言后才会被机器执行。高级语言的表示方式比低级语言更位人性化,更易学,易用和易维护,但性能方面比低级语言更为低效。

1.2 成分性质分类

  • 动态语言:指程序在运行时可以改变其结构,新的函数可以被引进,已有的函数可以被删除等结构上变化,大部分情况下,动态语言都是解释性语言。常见的动态语言有:PHP、JavaScript、ASP、CGI、Lisp、Perl、Python、Ruby
  • 静态语言:程序所有的成分在编译时确定,在运行时不能改变。常见的静态语言有:C++、Java、Delphi、C#

1.3 按理论基础分类

  • 函数式语言:又称泛函编程,是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免状态以及可变数据。函数编程语言最重要的基础是λ演算。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。和命令式编程相比,函数式编程强调函数的计算比指令的运行重要。和程序编程相比,函数式编程裹,函数的计算可随时调用。函数式语言主要用于人工智能领域。函数式编程中任何一段程序都是一个函数。
  • 逻辑型语言:又称诺伊曼式语言,其建立在关系理论和一阶谓语理论基础上,具有很强的推理功能和可读性。用于书写自动定理证明,专家系统等(数学)问题的程序。
  • 脚本语言:又被称为动态语言,是为了缩短传统的编写-编译-链接-运行而建立一种编程语言,用来控制软件应用程序,脚本通常以文本保存,只在被调用时进行解释或编译。如 Python,JavaScript,PHP

2.高级语言

2.1 概念

  • 高级语言是一种独立于机器,面向过程或对象的语言,参照数学语言而设计,近似于日常会话的语言。
  • 高级语言使用语法来描述程序中运算步骤,控制结构和数据传输。
  • 计算机不能直接理解高级语言,只能直接理解机器语言(低级语言)所以必须把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
  • 翻译的方式有两种,一种是编译,一种是解释。

2.2 高级语言的编译

2.2.1 编译的定义

  • 编译需要计算机通过编译器把程序代码编译成为机器语言文件(目标程序文件),将源代码一次性转换成目标代码的过程,类似英语中的全文翻译。编译程序会将高级语言翻译成目标程序( 汇编语言或机器语言形式 ),进行汇编和连接后在计算机上执行。

2.2.2 编译的过程

  • 词法分析:对构成源程序的字符串进行扫描和分解,识别出所有单词符合。
  • 语法分析:在词法分析的基础上,根据语言的语法规则,把单词符号串分解成各类语法单位,如短语、句子等。编译正确的程序不应该存在语法错误。
  • 语义分析:分析程序中各种语法结构的语义信息,同时包括对静态语义如变量类型等内容的检查。需要注意的是,编译器不能对动态语义错误如死循环,变量未赋初值和除数为0等内容进行识别,这类错误只有在程序运行时才能被发现。
  • 中间代码生成和代码优化:对前段产生的中间代码进行加工变换,以期在最后阶段能产生出更为高效的目标代码。中间代码的生成有利于进行与机器无关的优化处理,也有利于编译程序的移植。需要注意的是,中间代码生成和代码优化不是每个编译器所必须的功能
  • 目标代码生成:生成特定机器上的低级语言代码。
  • 符号表管理和出错处理贯穿整个编译过程

2.2.3 编译的优缺点

  • 优点:使得计算机运行目标程序更为高效。
  • 缺点:修改源程序后需要重新编译才能再次运行目标程序。

2.2.4 反编译和交叉编译

  • 反编译:将可执行文件重新转换成汇编程序的过程,越是高级语言越难以反编译。
  • 交叉编译:在一个平台上生成另一个平台的可执行代码,比如在 Windows 平台上生成 Linux 平台的程序。

2.3 高级语言的解释

2.3.1 解释的定义

  • 解释性语言编写的程序不进行预先编译,直接以文本方式存储程序代码,代码即程序。
  • 在运行程序的时候,解释性语言会将源代码逐条转换成目标代码,并在解释的同时,逐条运行,类似英语中的同声传译。
  • 与编译不同的是,解释器能直接执行高级语言源代码或某种中间代码,不形成与源程序功能等价的目标程序。

2.3.2 解释的优缺点

  • 优点:交互性好,能一边执行,一边修改,中间代码独立于计算机,只要有相应的解释程序就能在任何计算机上运行。
  • 缺点:需要安装对应的解释程序,同时运行效率低于编译。

2.4 编译和解释的区别

  • 编译(Compile)的过程是把整个源程序代码翻译成另外一种代码,翻译后的代码等待被执行或者被优化等等,发生在运行之前,产物是另一份代码(目标程序文件)。
  • 解释(Interpret)的过程是把源程序代码一行一行的读懂,然后一行一行的执行,发生在运行时,产物是运行结果
  • 编译和解释的过程上的区别:编译是将源程序翻译成可执行的目标代码(目标程序文件),翻译与执行是分开的;而解释是对源程序的翻译与执行一次性完成,不生成可存储的目标代码。
  • 编译和解释结果上的区别:编译的话会把输入的源程序翻译生成为目标代码,并存下来(无论是存在内存中还是磁盘上),后续执行可以复用;解释的话则是把源程序中的指令逐条解释,不生成也不存下目标代码,后续执行没有多少可复用的信息。

3.低级语言(汇编)

3.1 汇编语言的特点

  • 汇编语言是面向机器的程序设计语言,利用计算机所有硬件特性并能直接控制硬件的语言。汇编语言又称为符号语言,使用助记符代替操作码,用地址符号代替地址码,使用符号代替机器语言的二进制代码,一般情况下比高级语言效率更高。
  • 在执行代码时,需要使用汇编程序将汇编语言编写的代码翻译成机器语言程序,再交由计算机运行。

3.2 汇编语言的翻译过程

  • 预处理:常规编译之前预先进行的工作,它读取C语言源文件,对其中以#开头的指令(伪指令)和特殊符号进行替换。伪指令主要包括文件包含、宏定义、条件编译指令。预处理程序对源程序进行上述“替换工作”后,输出的文件中将不再包含宏定义、文件包含、条件编译等指令。
  • 编译:对预处理后的输出文件进行词法分析与语法分析,试图找出所有不符合语法规则的部分,并根据问题的大小给出错误消息,终止编译,或者给出警告,继续做下去。在各部分都符合语法规则后,将其翻译为功能等价的中间代码表示或汇编代码(比较机械,效率不高)。
  • 汇编:将汇编语言代码翻译成目标机器代码的过程。目标文件由机器码组成。通常它至少有代码段和数据段两部分。前者包含程序指令,后者存放程序中用到的各种全局/静态数据。
  • 链接:解决外部符号访问地址问题,就是将一个文件中引用的符号与该符号在另一个文件中的定义连接起来,从而使有关的目标文件连成一个整体,最终成为可被操作系统执行的可执行文件。

3.3 汇编语言的优点

  • 面向机器的低级语言,为特定的设备专门设计。
  • 保持了机器语言的优点,具有直接和简洁的特点。
  • 可有效地访问并控制计算机的各种硬件设备,如磁盘,存储器,I/O 端口。
  • 目标代码简短,占用内存少,执行速度快,高效。
  • 可以与高级语言配合使用。

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

4.1 数据

4.1.1 标识符

  • 标识符(identifier)是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。
  • 在计算机编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块,数据类型等命名,以建立起名称与使用之间的关系。标识符通常由字母和数字以及其它字符构成。

4.1.2 变量

  • 变量必须具有标识符,即变量的名称。
  • 变量必须具有数据类型,数据类型决定了变量值的表现形式和分配内存空间的大小(某些编程语言会自动分配数据类型,而某些需要手动指定)。
  • 根据变量作用域的不同,变量分为局部变量和全局变量。
  • 在内存中,供变量使用的存储空间有 3 个,即程序区,静态存储区和运行栈区。
    • 程序区存放程序的可执行代码模块。
    • 静态存储区存放所有全局变量以及标明为静态类的局部变量。
    • 运行栈区存放所有局部变量,包含现场所用的数据和函数的形参。

4.2 函数调用

4.2.1 形参与实参

  • 形参:形式参数,函数定义时设置的变量参数。其没有给定值,仅具有可以接受实际参数的意义,处理时也不会立即为其分配存储空间。只有当函数被调用且启动时,才会使用,在函数调用结束后释放。
  • 实参:实际参数,在调用函数时给出,由实参将数据通过堆栈传输给形参。

4.2.2 传值和传址调用

  • 传值调用:实参的值传递复制给形参,实参可以是表达式或常量,也可以是变量或数组元素,这种传递是单向的,形参不能将值传回实参。
  • 传址调用(引用调用):实参的地址传递给形参,实参必须是变量,数组名或数组元素,不能是表达式或常量,这种情况下形参的修改会同步到实参上。

4.2.3 运算精度

  • 在程序中,若表达式中的算术运算对象类型不同,为保证运算精度,应当将精度较小的向精度较大的靠拢。
  • 比如,整型与双精度浮点型相减,必须把整型转换为双精度浮点型,之后再进行两个浮点数的相减。

4.3.基本控制结构

4.3.1 顺序结构

  • 按照书写的先后顺序从前到后执行的结构。顺序结构是算法结构中最简单,也是最基本的结构。

4.3.2 分支结构

  • 分支结构其实就是选择结构,用于判断给定的条件,根据判断的结果来控制程序的流程。
  • 通常使用 if 语句来进行条件判断。

4.3.3 循环结构

  • 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,通常可以使用 for 或 while 语句来进行循环。
  • for 和 while 循环在进入循环前判断终止条件,而 do while 循环则在底部进行判断,先执行循环体一次再执行判断条件。
  • for 和 while 语言的循环体执行次数比循环条件的判断次数少 1,而 do while 的循环体执行次数等于循环条件的判断次数。

5.面向对象程序设计

5.1 基本概念

  • 面向对象程序设计(OOP)是一种以对象为核心计算机编程架构。
  • 该方法认为程序由一系列对象组成,类是对现实世界的抽象,表示静态属性的数据和对数据的操作,对象是类的实例化,对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。
  • 在面向对象的程序设计中,类和对象是组成程序的基本模块。
  • 常用的面向对象的程序设计语言有:Java,PHP,C++,C 等。

5.2 名词解释

  • 对象(Object) :可以对其做事情的一些东西。一个对象有状态、行为和标识三种属性。
  • 类(Class):一个共享相同结构和行为的对象的集合。类定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的事情。比如,狗这个类会包含狗的一切基础特征,例如它的孕育、毛皮颜色和吠叫的能力。类可以为程序提供模版和结构。一个类的方法和属性被称为成员。
  • 封装:第一层意思是将数据和操作捆绑在一起,创造出一个新的类型的过程;第二层意思是将接口与实现分离的过程。
  • 继承:类之间的关系,在这种关系中,一个类共享了一个或多个其他类定义的结构和行为。继承描述了类之间的父子关系。子类可以对基类的行为进行扩展、覆盖、重定义。
  • 组合:既是类之间的关系也是对象之间的关系。在这种关系中一个对象或者类包含了其他的对象和类。组合描述了包含关系。
  • 多态:类型理论中的一个概念,一个名称可以表示很多不同类的对象,这些类和一个共同超类有关。因此,这个名称表示的任何对象可以以不同的方式响应一些共同的操作集合。
  • 动态绑定:也称动态类型,指的是一个对象或者表达式的类型直到运行时才确定。通常由编译器插入特殊代码来实现。与之对立的是静态类型。
  • 静态绑定:也称静态类型,指的是一个对象或者表达式的类型在编译时确定。
  • 消息传递:指的是一个对象调用了另一个对象的方法(或者称为成员函数)。
  • 方法:也称为成员函数,是指对象上的操作,作为类声明的一部分来定义。方法定义了可以对一个对象执行那些操作。

5.3 特点

  • 封装性
  • 继承性
  • 多态性

6.C 程序设计语言

6.1 C 的关键字(特别)

auto声明自动变量
const定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
enum声明枚举类型
extern声明变量或函数是在其它文件或本文件的其他位置定义
goto无条件跳转语句
long声明长整型变量或函数返回值类型
register声明寄存器变量
short声明短整型变量或函数
signed声明有符号类型变量或函数
sizeof计算数据类型或变量长度(即所占字节数)
struct声明结构体类型
typedef用以给数据类型取别名
unsigned声明无符号类型变量或函数
union声明共用体类型
volatile说明变量在程序执行中可被隐含地改变

6.2 C 的运算符(特别)

运算符描述实例
%取模运算符,整除后的余数20 % 10 将得到 0
++自增运算符,整数值增加 1A++ 先取值后自增,B = 10++,则 B=10
自减运算符,整数值减少 1–A 先自减后取值,B = –10,则 B=9
&位与运算,与 && 不同只有两个数的二进制同时为1,结果才为1,否则为0
|位或运算,与 || 不同参加运算的两个数只要两个数中的一个为1,结果就为1
^位异或运算参加运算的两个数,如果两个相应位的值不同,则该位结果为1
~取反~ 01 = - 10 = -2
+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C += A 相当于 C = C + A
sizeof()返回变量的大小sizeof(a) 将返回 4,其中 a 是整数
&返回变量的地址&a,将给出变量的实际地址
*指向一个变量* a,将指向一个变量
Z ? X : Y条件表达式如果条件 Z 为真,则值为 X,否则值为 Y

6.3 多维数组

  • C 支持多维数组:type name[size1][size2]...[sizeN];
  • 比如声明一个 x 行 y 列的二维整型数组:type arrayName [ x ][ y ];
  • 比如声明一个行数据不定,列最多 3 行的数据:type arrayName [][ y ];,此时数据可以为 [{1,2,3}, {2,3}, {4}],系统会自动填充 0,使之成为一个 3 行 3 列的二维数组。

6.4 指针

  • &a:将给出变量的实际地址,a表示的变量。
  • *a,将指向一个变量,a表示的内存地址。
  • 指针是 C 程序设计语言中对内存的操作。

7.其他

7.1 文法

  • 文法是用来描述语言的语法成分结构构造的形式规则, 通常用 G 表示。
  • 一个语法成分由句子和构成句子的单词组成,语言由句子组成。
  • 文法 G:S — A0 | B1,A — S1 | 1,B — S0 | 0
  • 结果为 10:S —> A0,A —> 1,A0 —> 10
  • 结果为 01:S —> B1,B —> 0,B0 —> 01
  • 结果为 1010:S —> A0,A —> S1,( S —> A0,A —> 1 )—> 10,( A —> S1 )—> 101,最终结果( S —> A0 )—> 1010

7.2 正规式

正规式正规集
a{a}
a|b{a,b}
ab{ab}
(a|b)(a|b){aa,ab,ba,bb}
a*{ε, a, aa, a…aaa}
(a|b)*{ε, a, b, aa, ab, ba, bb, aaa, bbb, 所有由 a 和 b 组成的串}

PS:空字符串 ε,空语句 Φ

7.3 有限自动机

  • 有限自动机( Finite Automata ),又称时序机,它由一个有限的内部状态集和一组控制规则组成,通过给定的规则来控制在当前状态下读入输入符号后应转向什么状态。
  • 有限状态自动机从初始状态开始,依次读取字符,符合条件的则进行状态转移,反之抛弃,直至字符串被读完,状态由初态到终态(双圈)。
  • 在状态转移的每一步,根据有限自动机当前所处的状态和所面临的输入符号,便能唯一地确定有限自动机的下一个状态,这样的有限自动机称为确定的有限自动机( DFA )
  • 若有限自动机根据当前所处的状态和所面临的输入符号,能够确定的后继状态不是唯一的,就称这样的有限自动机为不确定的有限自动机( NFA )。

7.4 表达式

7.4.1 表达式的分类

  • 前缀表达式:+ab
  • 中缀表达式:a+b
  • 后缀表达式:ab+
  • 前后中是指操作符与两个操作数之间的关系。 操作符在两个操作数前就是前缀;在两个操作数后就是后缀;在两个操作数中间就是中缀。
  • 后缀式又称逆波兰式。在计算机逆波兰式求解时就会用到栈,也就是栈的典型的应用就是表达式的求值。

7.4.2 后缀式的转换

  • 中缀式可以通过构造二叉树,通过后序遍历二叉树的方法求得后缀式,通过先序遍历二叉树的方法求得前缀式。
  • 后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素。
  • 先序遍历的实现思想是:从根节点出发,先访问根节点,再访问当前节点的左子树,若当前节点无左子树,访问当前节点的右子树,直至所有元素被访问。
  • 中序遍历的实现思想是:从当前节点出发,先访问当前节点的左子树,再访问根节点,最后再访问右子树。
  • 例如算式: ( 1 + 2 ) * 3 + 2 * 1
  • 后序遍历:1 2 + 3 * 2 1 * +
  • 先序遍历: + * + 1 2 3 * 2 1
  • 中序遍历:( 1 + 2 ) * 3 + 2 * 1

7.5 高级语言分类