了解程序是如何被计算机理解和执行的,对于理解数据库内核、存储过程、触发器以及SQL查询的处理过程至关重要。
程序设计语言是用来定义计算机程序的符号系统,它允许程序员以人类可读的方式向计算机发出指令
关键字:又称保留字,是语言中具有特殊含义的单词,例如if、else、while、int、class等,不能用作标识符。
标识符:由程序员定义的名称,用于代表变量、常量、函数、数据类型等程序对象。
常量与变量:常量是在程序运行过程中其值不能被改变的量;变量是其值可以在程序运行中被改变的量,是内存中数据存储空间的抽象。
数据类型:定义了数据的取值范围和可进行的操作。
运算符:用于对数据进行操作的符号。
表达式:由操作数和运算符组成的式子,可以计算出一个值。
语句:程序中最基本的执行单位,用于完成一定的操作任务。
面向对象的程序设计语言 (Object-Oriented Programming, OOP):其核心概念是类和对象。它将数据和对数据的操作封装在一起,支持继承、多态等特性,极大地提高了代码的可重用性和可维护性。典型代表有C++、Java和C#。
函数式语言 (Functional Languages):将计算看作是数学函数的求值过程,避免使用程序状态和可变数据。
逻辑语言 (Logic Languages):基于形式逻辑,通过推理来解决问题。Prolog是主要代表。
脚本语言 (Scripting Languages):通常用于控制软件应用程序,将应用程序联系起来,或用于快速编程。它们通常是解释执行的,如Perl、Python、Ruby、JavaScript、Shell等。
一个重要的区别是:HTML不是编程语言。它是超文本标记语言(Hyper Text Markup Language),用于定义网页的结构和内容,而不是用于逻辑控制和计算的编程指令
语言处理程序是介于用户程序与计算机硬件之间的重要系统软件,其任务是将程序员用高级语言编写的源代码翻译成计算机能够执行的机器码。
汇编程序 (Assembler):将汇编语言(介于机器语言和高级语言之间的符号化语言)翻译成机器语言。汇编指令与机器指令之间基本上是一一对应的关系。
编译程序 (Compiler):将高级语言源程序一次性整体翻译成目标程序(通常是机器代码)。编译过程分为前端和后端,前端是机器无关部分,后端是机器相关部分。C、C++、Java等语言采用这种编译方式。编译方式下,用户程序运行速度更快。
解释程序 (Interpreter):不事先将源程序编译成目标代码,而是逐行读取源程序,边分析边执行。脚本语言如JavaScript、Shell通常采用解释执行方式。
编译过程
词法分析:从左到右逐个字符扫描源程序,识别出一个个“单词”(Token),如关键字、标识符、常数、运算符等。
语法分析:根据语言的语法规则,将词法分析得到的单词序列进行解析,检查其结构是否符合语法要求,并构造出语法分析树。
语义分析:判断源程序的语义是否正确,例如类型是否匹配、变量是否先声明后使用等。
中间代码生成:将语法分析树或经过语义分析的源程序转换为一种内部表示形式(中间代码)。常用的中间码形式有后缀式(逆波兰式)、三地址码和抽象语法树等。
代码优化:对中间代码进行等价变换,以期生成更高效的目标代码。
目标代码生成:将优化后的中间代码翻译成最终的目标机器代码。
符号表:是编译器用来记录源程序中各种标识符(如变量名、函数名)的属性和特征信息的数据结构,比如它的类型、作用域、存储地址等。在词法分析、语法分析和语义分析阶段,编译器会不断地查找、填入或更新符号表。
函数调用和返回控制是用栈实现的,在程序运行期间,函数的调用和返回遵循“后进先出”(LIFO)的规则。因此,操作系统和运行时环境使用栈结构来管理函数调用,每个函数调用在栈上分配一个“栈帧”,用于存放其局部变量、参数和返回地址。函数返回时,其对应的栈帧被弹出。
编译方式是将源代码一次性转换成目标代码(机器码),后续运行时直接执行目标代码,因此速度更快。解释方式则是逐条翻译并立即执行,不生成独立的目标程序,因此运行速度相对较慢。
“编译程序不参与用户程序的运行控制”意味着执行的是编译后的目标代码,编译器本身已经退出了;“解释程序参与”意味着解释器本身一直在内存中运行,控制着整个执行流程。
程序运行时的存储组织
程序在运行的时候,其内存空间的组织方式对于理解数据库内部的内存管理非常重要。通常分为以下几个部分:
程序代码区:存放程序的机器指令。
静态数据区:存放已初始化的全局变量和静态变量。这些变量的生命周期是整个程序运行期。
栈 (Stack):又称动态数据区,用于存放函数调用过程中的局部变量、函数参数和返回值。栈的特点是“后进先出”,函数调用时分配,返回时释放。
堆 (Heap):又称动态数据区,用于存放程序运行过程中动态申请和释放的内存(如C语言中的malloc/free,C++中的new/delete)。堆的分配和释放由程序员控制,比栈更灵活,但管理也更复杂。
在高级语言源程序中,为变量分配的存储单元地址通常属于逻辑地址,在运行时才转换为物理地址
传值调用方式下,数据是实参向形参的单向流动。引用调用方式下,可以实现形参和实参间双向传递数据的效果。
传值调用的实参要求可以是变量,常量,表达式(有确定的值)。引用调用的实参必须是变量(内存地址中的左值)
C语言基本类型传参、默认的简单类型传递。C++引用(&)、Java/C#中的对象传参。
评论