软考中级软件设计师——程序设计语言篇

一、低级语言和高级语言

  • 机器语言:计算机硬件能识别的由 0、1 组成的机器指令序列,是最基本语言,特定系统固有,面向机器,程序设计效率低、可读性差、难修改维护 。
  • 汇编语言:用易记忆符号代替机器指令(如 ADD 表示加法、SUB 表示减法 ),汇编指令集合构成汇编语言,与机器语言接近,仍面向机器。机器语言和汇编语言统称低级语言。
  • 高级语言:功能更强、抽象级别更高,面向各类应用,如 Java、C、C++、PHP、Python 等,与自然语言接近,提高程序设计效率。

二、编译程序和解释程序

  • 解释程序:直接解释执行源程序或先翻译成中间代码再执行。运行时解释程序和源程序参与过程,不生成独立目标程序。
  • 编译程序:将源程序翻译成目标语言程序再执行。运行的是目标程序,源程序和编译程序不参与执行过程,会生成独立保存的目标程序。

三、程序设计语言基本成分

1、数据成分

  1. 常量与变量
    • 常量:程序运行时值不变的数据,如整数常量 5、字符串常量 "hello",放在常量池里。
    • 变量:值可改变的数据容器,需定义类型(如 C 语言中 int num;),按作用域分为全局变量(存储空间运行中一般不变)和局部变量(存储单元动态改变)。所分配的地址是逻辑地址
  2. 数据类型
    • 基本类型:整型(如 int)、字符型(如 char)、实型(floatdouble)、布尔类型(bool)。
    • 构造类型:数组(相同类型元素集合,如 int arr[10];)、结构体(组合不同类型数据,如 C 语言 struct Student {int id; char name[20];};)、联合(成员共享内存,大小取决于最大成员)。
    • 其他类型:指针类型(type *)、抽象数据类型(如类类型)、空类型(void)、枚举类型(enum)。

注意:许多程序设计语言规定,程序中的数据都必须具有类型,其作用包括:

  • 便于为数据合理分配存储单元。
  • 便于对参与表达式计算的数据对象进行检查。
  • 便于规定数据对象的取值范围及能够进行的运算。

2、运算成分

  1. 算术运算:如 +(加)、-(减)、*(乘)、/(除)、%(取余)。
  2. 逻辑运算:如 &&(逻辑与)、||(逻辑或)、!(逻辑非)。
  3. 关系运算:如 >(大于)、<(小于)、==(等于)、!=(不等于)。
  4. 运算优先级与结合性:优先级高的先运算(如 * 高于 +);优先级相同则按结合性确定顺序(如赋值运算符右结合)。

3、控制成分

  1. 顺序结构:按语句先后顺序依次执行。
  2. 选择结构
    • if - else:如 if (条件) {执行语句1} else {执行语句2}
    • switch - case:多分支选择,switch (表达式) {case 值1: 语句1; break;...}
  3. 循环结构
    • while:先判断条件,如 while (条件) {循环体}
    • do - while:先执行循环体再判断条件,do {循环体} while (条件)
    • forfor (初始化; 条件; 增量) {循环体},常用于已知循环次数的场景。

4、函数相关

  1. 函数定义:由函数名、参数列表、返回值类型和函数体组成(如 C 语言 int sum(int x, int y) { return x + y; })。
  2. 参数传递
    • 传值调用:实参值单向传递给形参,形参修改不影响实参,实参可以是常量、变量或表达式,不可以实现形参和实参间双向传递数据的效果。函数运行时仅对形参内存单元的数据进行操作,实参内存单元的数据保持不变。
    • 引用调用:传递实参地址(如 C++ 中 void swap(int &x, int &y)),形参修改影响实参,实参必须是变量,可以实现形参和实参间双向传递数据的效果形参不重新分配内存,而是与实参共用同一内存空间(或通过地址间接操作实参内存)。函数中对形参的修改,实质是对实参内存单元数据的修改。

四、编译程序和解释程序翻译阶段

1.编译方式的阶段

        包括词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成。其中,中间代码生成和代码优化并非必需,可省略,即编译器可在词法分析、语法分析、语义分析后直接生成目标代码。

2.解释方式的阶段

        仅包含词法分析、语法分析、语义分析。

五、符号表

        不断收集、记录和使用源程序中一些相关符号的类型和特征等信息,并将其存入符号表中。
记录源程序中各个字符的必要信息,以辅助语义的正确性检查和代码生成。

        通常包含符号名称、符号类型(变量、函数等)、符号地址、作用域、数据类型、存储单元长度等属性。

        在编译程序工作时,符号表伴随词法分析、语法分析、语义分析等阶段,记录和管理符号信息。例如,在语义分析中检查类型匹配等静态语义时,需借助符号表中的类型信息;在链接阶段,通过符号表找到函数地址完成链接。

六、编译过程描述

 1.预处理(Preprocessing)

  • 任务:处理源代码中以 # 开头的预编译指令,如 #include(包含头文件)、#define(宏定义展开)、条件编译指令(#if#ifdef 等),删除注释,添加行号和文件名标识,保留 #pragma 等编译器指令。
  • 输出:生成经过预处理的源代码文件(如 .i 或 .ii 为扩展名)。

2. 编译(Compilation)

  1. 词法分析:从左至右扫描字符流,识别单词符号(如关键字、标识符、运算符等),输入源程序,输出记号流。分析构成程序的字符及由字符按照构造规则构成的符号是否符合程序语言的规定。
  2. 语法分析:将单词符号序列分解为语法单位(如表达式、语句),检查语法结构是否符合规则,构建语法树,发现语法错误并提示。语法分析阶段可以发现程序中所有的语法错误。输入:记号流;输出:语法树(分析树)。
  3. 语义分析:审查静态语义(如类型匹配、变量作用域),收集符号类型信息,检测语义错误(如非法类型操作)。输入是语法树(分析树),主要作用是进行类型分析和检查。语义分析阶段不能发现程序中所有的语义错误。不能发现动态语义错误,动态语义错误只能在运行时才能发现。
  4. 中间代码生成(可选):将源程序转换为与机器无关的中间表示(如三地址码、四元式)。常见的中间代码有:后缀式、三地址码、三元式、四元式和树(图)等形式。中间代码与具体的机器无关(不依赖具体的机器),可以将不同的高级程序语言翻译成同一种中间代码。中间代码可以跨平台。因为与具体的机器无关,使用中间代码有利于进行与机器无关的优化处理和提高编译程序的可移植性。
  5. 优化(可选):对中间代码或目标代码进行等价变换,提升时空效率(如删除多余运算、循环优化)。
  6. 目标代码生成:将中间代码或优化后的代码转换为汇编语言代码(如 .s 文件)。目标代码生成阶段的工作与具体的机器密切相关,寄存器的分配工作处于目标代码生成阶段。

3. 汇编(Assembly)

  • 任务:通过汇编器将汇编语言代码逐句转换为机器可执行的二进制指令。
  • 输出:生成可重定位目标文件(如 .obj.o 或 .elf 为扩展名),包含代码段(程序指令,可读可执行)和数据段(全局或静态数据)。

4. 链接(Linking)

  • 任务:链接器合并多个目标文件(.o)和库文件(静态库或动态库),解析符号引用(如函数、变量地址),处理重定位(调整相对地址为绝对地址),生成最终可执行文件(如 .exe.out)。
    • 静态链接:将库函数代码直接拷贝到可执行文件中。
    • 动态链接:记录库文件信息,运行时加载库到内存,供程序调用。

七、正规式(词法分析阶段)

基本元素

  • ε(空串):表示只包含空串的集合。
  • ∅(空集):表示不包含任何字符串的集合。
  • 单个字符:如 a,表示只包含字符 a 的集合。

基本运算

  • 或(|):若正规式 R 和 S,则 R∣S 表示两者的并集,即满足 R 或 S 的字符串集合。例如,a∣b 表示字符串为 a 或 b
  • 连接(・):R⋅S(常省略为 RS),表示 R 中字符串与 S 中字符串连接后的集合。如 a(b∣c) 表示 ab 或 ac
  • 闭包(*):R∗ 表示 R 中字符串的任意次连接(包括 0 次,即 ε)。例如,(a∣b)∗ 表示由 a 和 b 组成的任意长度字符串(含空串)。

示例

  • (a∣b)∗ab:表示以 ab 结尾,由 a 和 b 组成的任意字符串(如 abaababb 等)。
  • a∗b∗:表示先有任意个 a(含 0 个),后接任意个 b(含 0 个)的字符串(如 ε、abaaabbb 等)。

等价性

若两个正规式描述的正规集相同,则它们等价。例如:

  • (a∣b) 与 (b∣a) 等价,均表示单个字符为 a 或 b
  • (a∗b∗)∗ 与 (a∣b)∗ 等价,均表示由 a 和 b 组成的任意字符串(含空串)。

八、有限自动机(词法分析工具)

  1. 定义与分类
    • 确定有限自动机(DFA):五元组 M=(S,∑,f,s0​,Z),其中 S 是有限状态集,∑ 是有穷字母表,f:S×∑→S 是单值转换函数(对每个状态和输入符号,唯一确定下一状态),s0​∈S 是唯一初始状态,Z⊆S 是终止状态集。对每一个状态来说识别字符后转移的状态是唯一的。
    • 不确定有限自动机(NFA):五元组 M=(S,∑,f,S0​,Z),f:S×∑→2S(转换函数值为状态集,同一输入可对应多个后继状态),S0​⊆S 是初始状态集(可为多个状态),其余同 DFA。对每一个状态来说识别字符后转移的状态是不唯一的。
  2. 两者区别
    • 转换函数:DFA 是单值映射,NFA 是多值映射(到状态集)。
    • 初始状态:DFA 是唯一初始状态,NFA 是初始状态集。
    • 状态转移:DFA 每步转移唯一,NFA 不唯一。
  3. 有限自动机与正规式
    • 有限自动机(DFA、NFA)与正规式描述能力等价,可识别正规集。例如,NFA 可通过子集构造算法转换为等价 DFA,便于机器实现。
  4. 表示方法
    • 状态转换图:结点表示状态(双圈为终态),有向弧表示状态转移,弧上标记输入符号。
    • 状态转换表:二维表形式,行表示当前状态,列表示输入符号,表项为下一状态。

九、上下文无关文法

一、形式定义

上下文无关文法 G 是一个四元组 G=(VT​,VN​,S,P),其中:

  • VT​:终结符集合(非空),构成语言的基本符号,如程序设计语言中的关键字、运算符、常量等,不可再分解。
  • VN​:非终结符集合(非空),且 VT​∩VN​=∅,表示语法结构或短语的集合,可进一步推导。
  • S:开始符号,S∈VN​,代表文法最终感兴趣的语法单位,是推导的起始点。
  • P:产生式集合(有限),每个产生式形式为 A→α(A∈VN​,α∈(VT​∪VN​)∗),表示非终结符 A 可被替换为符号串 α。

二、关键特性

  • “上下文无关”:在推导过程 αAβ⇒αγβ 中,非终结符 A 被 γ 替换时,无需考虑 A 出现的上下文 α 和 β。
  • 语言生成:通过不断应用产生式规则,从开始符号 S 推导出终结符串,所有可推导出的终结符串构成该文法生成的语言 L(G)。

三、典型应用

  • 程序设计语言语法描述几乎所有程序设计语言的语法都由上下文无关文法定义,如算术表达式 E→E+E∣E×E∣(E)∣id,清晰描述表达式结构。
  • 语法分析:借助上下文无关文法,可构造语法分析算法(如 LR 分析器、LL 分析器),检验字符串是否符合文法规则,识别语法错误。

十、语法树中、后序遍历

一、中序遍历(In-order Traversal)

规则:左子树 → 根节点 → 右子树(左 - 根 - 右)。

表达式语法树中的应用

  • 对于 二元运算表达式(如 A + B * C),中序遍历结果为 中缀表达式,但需根据运算符优先级和结合性确定是否添加括号。
  • 示例
    表达式 (a + b) * c 的语法树结构:
    *  
   / \  
  +   c  
 / \  
a   b  

中序遍历顺序:

  1. 左子树(+ 的中序遍历:a + b
  2. 根节点(*
  3. 右子树(c

结果a + b * c ❌(错误,原表达式有括号)→ 实际应保留括号逻辑,正确中序遍历需根据语法树结构反映优先级,此处原表达式括号表示 + 优先于 *,但中序遍历本身不自动添加括号,需结合语法规则判断。

二、后序遍历(Post-order Traversal)

规则

左子树 → 右子树 → 根节点(左 - 右 - 根)。

表达式语法树中的应用

  • 后序遍历结果为 后缀表达式(逆波兰式),无需括号即可明确运算顺序(操作符在操作数之后)。
  • 示例
    表达式 (a + b) * c 的语法树后序遍历:
    1. 左子树(+ 的后序遍历:a b +
    2. 右子树(c
    3. 根节点(*
      结果a b + c *(正确后缀表达式)。

十一、遍历与语法分析的结合

1.递归下降分析法

        通过递归函数模拟语法树的构建过程,每个非终结符对应一个函数,按前序遍历顺序展开推导。递归下降分析法属于 自上而下分析,其推导过程与前序遍历一致。

2.移进一归约分析法

        移进一归约分析法是编译程序(或解释程序)对高级语言源程序进行语法分析的一种
方法,属于自底向上(或自下而上)的语法分析方法。

十二、操作符优先级与结合性的细节处理

  1. 优先级判断的边界情况

    • 当操作符优先级 相等 时(如 * 和 /),需根据 结合性 决定处理顺序:
      • 左结合操作符(如 a * b / c):栈顶同优先级操作符需先弹出(如 * 和 / 相遇时,先弹出栈顶的 * 再压入 /)。
      • 右结合操作符(如赋值符 =,但算术运算中较少见):需调整逻辑(同优先级时不弹出栈顶,直接压栈)。
    • 软考陷阱:若题目未明确结合性,默认按左结合处理(如常见的加减乘除)。
  2. 括号的特殊处理

    • 左括号 ( 仅用于标记优先级边界,栈中遇到右括号 ) 时,需弹出直到左括号(左括号不加入结果)。
    • 嵌套括号的情况(如 ((a + b) * c)):严格遵循 “遇右括号弹栈至左括号” 的规则。

十三、程序语言的分类及特点

  1. 命令式语言
    • 特点:基于动作和语句执行,通过改变程序状态完成任务,遵循冯・诺依曼体系结构。常见的有 C、Fortran 等。
    • 考点:变量的存储与使用、语句执行顺序、控制结构(顺序、选择、循环)的实现。例如,在 C 语言中,如何使用forwhiledo - while循环结构解决实际问题。
  2. 面向对象语言
    • 特点:以对象为基本单位,封装数据和操作,支持继承、多态和封装。如 Java、C++、Python(支持面向对象编程范式)。
    • 考点:类和对象的概念、继承的实现方式(单继承、多继承)、多态的类型(编译时多态、运行时多态)。例如,在 Java 中,通过方法重载和方法重写实现多态。
  3. 函数式语言
    • 特点:将计算视为函数的求值,避免使用共享状态和可变数据,强调函数的纯粹性和不可变性。如 Lisp、Haskell。
    • 考点:高阶函数的使用(函数作为参数、返回值)、递归的应用、闭包的概念。例如,在 Lisp 中,使用递归实现列表的操作。
  4. 逻辑式语言
    • 特点:基于逻辑推理,通过事实和规则描述问题,使用逻辑推理引擎求解。如 Prolog。
    • 考点:事实和规则的定义、查询的编写、回溯机制。例如,在 Prolog 中,定义家族关系的事实和规则,并进行查询。

十四、常见程序语言的特性对比

  1. C 和 C++
    • C 语言:面向过程的语言,语法简洁,执行效率高,常用于系统软件和嵌入式开发。
    • C++ 语言:在 C 语言基础上引入面向对象编程,支持类、对象、继承、多态等特性,同时保留了 C 语言的高效性,广泛应用于游戏开发、图形处理等领域。
    • 考点:C++ 相对 C 语言新增的特性,如类和对象的定义、构造函数和析构函数的使用、运算符重载等。
  2. Java 和 Python
    • Java 语言:跨平台性强,具有自动内存管理(垃圾回收机制),安全性高,广泛应用于企业级应用开发。
    • Python 语言:语法简洁易懂,具有丰富的库和框架,开发效率高,常用于数据分析、人工智能、Web 开发等领域。
    • 考点:Java 的面向对象编程和多线程编程,Python 的数据处理和机器学习库的使用。
  3. JavaScript 和 TypeScript
    • JavaScript 语言:是一种脚本语言,主要用于 Web 前端开发,实现网页的交互效果。
    • TypeScript 语言:是 JavaScript 的超集,增加了静态类型检查,提高了代码的可维护性和可靠性,常用于大型 Web 项目开发。
    • 考点:JavaScript 的事件处理机制、异步编程(回调函数、Promise、async/await),TypeScript 的类型系统和接口定义。

十五、程序语言的应用场景

  1. Web 开发
    • 前端:HTML、CSS、JavaScript 用于构建网页的结构、样式和交互效果。框架如 React、Vue.js、Angular 等提高开发效率。
    • 后端:Python(Django、Flask)、Java(Spring Boot)、Node.js(Express)等用于处理业务逻辑和数据存储。
    • 考点:前后端交互的方式(RESTful API、GraphQL)、Web 框架的基本使用。
  2. 数据科学和人工智能
    • 数据处理:Python 的 NumPy、Pandas 库用于数据的存储、处理和分析。
    • 机器学习Scikit - learn、TensorFlow、PyTorch 等库用于构建和训练机器学习模型。
    • 考点:数据预处理的方法、机器学习算法的原理和使用。
  3. 嵌入式系统开发
    • C 和 C++:由于其高效性和对硬件的直接控制能力,常用于嵌入式系统开发。
    • 考点:嵌入式系统的内存管理、中断处理、硬件驱动开发。

十六、程序语言的语法细节

  1. 变量声明和作用域
    • 不同语言的变量声明方式不同,如 C 语言需要显式声明变量类型,Python 是动态类型语言。
    • 变量的作用域分为全局作用域和局部作用域,了解不同语言如何处理变量的作用域是考点之一。例如,在 C 语言中,全局变量和局部变量同名时的处理方式,在 C 语言里,当全局变量和局部变量同名时,遵循局部优先原则,全局变量会被暂时隐藏。
  2. 异常处理
    • 不同语言有不同的异常处理机制,如 Java 使用try - catch - finally语句,Python 使用try - except - finally语句。
    • 考点:异常处理的语法结构、异常类型的分类和捕获。
  3. 文件操作
    • 各种语言都提供了文件操作的功能,如读取文件、写入文件、文件指针的移动等。
    • 考点:文件操作的函数和方法的使用、文件的打开和关闭模式。

十七、补充

        鉴于关于python相关的知识点比较多,故总结了一些相关的考点如下:

一、基础语法与数据类型

  1. 变量与赋值
    • 动态类型:Python 是动态类型语言,变量在赋值时自动确定类型,例如:
      a = 10  # 整数类型
      a = "hello"  # 字符串类型
    • 多重赋值:可同时为多个变量赋值,如 a, b = 1, 2
  2. 数据类型
    • 基本数据类型:包括整数(int)、浮点数(float)、字符串(str)、布尔值(bool)等。
    • 复合数据类型
      • 列表(list:可变、有序的数据集合,支持索引、切片、追加、插入等操作。例如 my_list = [1, 2, 3]my_list.append(4),其元素可以重复
      • 元组(tuple:不可变、有序的数据集合,使用小括号定义,如 my_tuple = (1, 2, 3)不可以重复
      • 集合(set:无序、唯一的数据集合,支持交集、并集、差集等操作。例如 set1 = {1, 2, 3}set2 = {3, 4, 5}set1.intersection(set2),集合里不能有重复的元素。
      • 字典(dict:键值对的集合,键必须唯一,如 my_dict = {'name': 'Alice', 'age': 20},字典的键不能重复但值可以重复。
  3. 控制结构
    • 条件语句if - elif - else 结构,根据条件执行不同的代码块。例如:
      x = 10
      if x > 5:
          print("x 大于 5")
      elif x == 5:
          print("x 等于 5")
      else:
          print("x 小于 5")
    • 循环语句
      • for 循环:用于遍历可迭代对象,如列表、字符串等。例如 for i in [1, 2, 3]: print(i)
      • while 循环:根据条件重复执行代码块,如 while x < 10: x += 1

二、函数与模块

  1. 函数定义与调用
    • 定义函数:使用 def 关键字定义函数,如 def add(a, b): return a + b
    • 参数传递:支持位置参数、关键字参数、默认参数和可变参数。例如:
      def func(a, b=2, *args, **kwargs):
          pass
    • 返回值:函数可以返回单个值或多个值(以元组形式)。
    • 模块与包
      • 模块:一个 Python 文件就是一个模块,可通过 import 语句导入使用,如 import mathmath.sqrt(4)
      • :包含多个模块的文件夹,需包含 __init__.py 文件(Python 3.3 及以后版本不是必需的)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值