- bitworld 的博客
GESP复习手册-2级
- @ 2026-1-16 15:57:44
1. 计算机系统概述
1.1 冯·诺依曼体系结构
现代计算机大多基于冯·诺依曼体系结构,其核心思想包括:
- 采用二进制表示数据和指令
- 程序和数据存储在存储器中,可被自动执行
- 计算机由五大基本部件组成:
- 运算器
- 控制器
- 存储器
- 输入设备
- 输出设备
重点:这是现代计算机的基本设计蓝图,理解它有助于掌握计算机的工作原理。
2. 计算机硬件组成
2.1 CPU(中央处理器)
CPU是计算机的“大脑”,负责执行指令和处理数据。
2.1.1 CPU的组成
- 运算器:执行算术运算(加减乘除)和逻辑运算(与或非)
- 控制器:协调控制各部件工作(取指令、分析指令、执行指令)
- 寄存器:高速存储部件,临时存放CPU正在处理的数据和指令
2.1.2 CPU性能指标
| 指标 | 说明 | 影响 |
|---|---|---|
| 主频 | CPU时钟频率(Hz) | 频率越高,单位时间执行指令越多 |
| 核心数 | CPU中独立运算核心数量 | 核心越多,多任务处理能力越强 |
| 字长 | CPU一次能处理的二进制位数 | 字长越长,处理能力越强(32位/64位) |
2.2 存储器层次结构
2.2.1 Cache(高速缓冲存储器)
- 位置:CPU与内存之间
- 作用:临时存储CPU频繁访问的数据和指令
- 特点:速度极快,容量小(L1<L2<L3)
- 工作方式:
- 命中:数据在Cache中找到,直接读取
- 未命中:数据不在Cache中,从内存读取并加载到Cache
2.2.2 内存(主存储器)
- 特点:
- 直接与CPU交换数据
- 存取速度快
- 容量相对较小
- 断电后数据丢失
- 分类:
- RAM(随机存取存储器)
- DRAM:速度较慢,成本低(主流内存)
- SRAM:速度快,成本高
- ROM(只读存储器):存储BIOS等固件,断电不丢失
- RAM(随机存取存储器)
2.2.3 外存(辅助存储器)
- 特点:
- 容量大
- 断电后数据不丢失
- 速度慢,不能直接与CPU交换数据
- 常见类型:
- 硬盘(HDD):容量大、成本低、速度慢
- 固态硬盘(SSD):速度快、抗震、成本高
- 光盘:CD、DVD等
- U盘:便携移动存储
2.3 总线系统
总线是计算机各部件之间传输信息的公共通信干线。
| 总线类型 | 功能 | 特点 |
|---|---|---|
| 数据总线 | 传输数据信息 | 位数与CPU字长对应 |
| 地址总线 | 传输存储器地址信息 | 位数决定可访问的最大内存容量 |
| 控制总线 | 传输控制信号和时序信号 | 协调各部件工作 |
总线特点:共享性(同一时间只能一个设备发送,多个设备接收)
2.4 输入/输出设备
| 类型 | 设备示例 | 功能 |
|---|---|---|
| 输入设备 | 键盘、鼠标、扫描仪、摄像头、麦克风 | 向计算机输入数据和指令 |
| 输出设备 | 显示器、打印机、音箱、投影仪 | 将处理结果输出给人 |
3. 计算机软件系统
3.1 系统软件
管理、控制和维护计算机硬件和软件资源,为应用软件提供运行环境。
3.1.1 操作系统(OS)
- 功能:管理硬件和软件资源,控制程序执行,提供人机界面
- 示例:Windows、macOS、Linux、Android、iOS
3.1.2 语言处理程序
| 类型 | 工作方式 | 示例 |
|---|---|---|
| 编译器 | 整个源程序一次性翻译成目标程序 | C/C++编译器 |
| 解释器 | 逐行解释执行源程序 | Python解释器 |
| 汇编程序 | 将汇编语言转换为机器语言 | 汇编器 |
3.1.3 数据库管理系统(DBMS)
- 功能:管理数据库的建立、维护、查询、更新
- 示例:MySQL、Oracle、SQL Server
3.1.4 实用程序
- 功能:辅助计算机日常维护和管理
- 示例:杀毒软件、磁盘清理工具、备份软件
3.2 应用软件
为解决特定领域问题或满足特定需求而开发的软件。
| 类别 | 功能 | 示例 |
|---|---|---|
| 办公软件 | 日常办公处理 | Word、Excel、PowerPoint |
| 图形图像软件 | 图形设计、图像处理 | Photoshop、Illustrator |
| 多媒体软件 | 音频视频处理 | Premiere、Audition |
| 行业专用软件 | 特定行业应用 | 医疗管理系统、证券交易软件 |
4. 计算机网络基础
4.1 网络体系结构
4.1.1 OSI七层模型
| 层次 | 功能 | 示例/协议 |
|---|---|---|
| 物理层 | 传输原始比特流 | 网线、光纤、网卡 |
| 数据链路层 | 封装成帧,相邻节点可靠传输 | 以太网协议 |
| 网络层 | 源到目标主机数据传输,路由选择 | IP协议 |
| 传输层 | 端到端可靠数据传输 | TCP、UDP |
| 会话层 | 建立、维护、终止会话连接 | - |
| 表示层 | 数据编码、格式转换、加密解密 | |
| 应用层 | 为用户应用程序提供网络服务 | HTTP、FTP、SMTP |
4.1.2 TCP/IP四层模型
| 层次 | 对应OSI层 | 主要协议 |
|---|---|---|
| 网络接口层 | 物理层+数据链路层 | 以太网协议 |
| 网络层 | 网络层 | IP协议 |
| 传输层 | 传输层 | TCP、UDP |
| 应用层 | 会话层+表示层+应用层 | HTTP、FTP、DNS |
重点:TCP/IP是实际使用的模型,需重点掌握各层功能。
4.2 IP地址
4.2.1 IPv4地址
- 格式:32位二进制,点分十进制表示(如
192.168.1.1) - 每段范围:0-255
4.2.2 IPv4地址分类
| 类别 | 首字节范围 | 默认子网掩码 | 用途 |
|---|---|---|---|
| A类 | 1-126 | 255.0.0.0 | 大型网络 |
| B类 | 128-191 | 255.255.0.0 | 中型网络 |
| C类 | 192-223 | 255.255.255.0 | 小型网络 |
| D类 | 224-239 | - | 多播通信 |
| E类 | 240-255 | 实验研究 |
4.2.3 子网掩码
- 作用:区分IP地址中的网络部分和主机部分
- 示例:
192.168.1.100+255.255.255.0- 网络部分:
192.168.1 - 主机部分:
100
- 网络部分:
4.2.4 IPv6地址
- 背景:IPv4地址资源枯竭
- 格式:128位二进制,8组4位十六进制数(如
2001:0db8:85a3::8a2e:0370:7334)
4.3 域名系统(DNS)
4.3.1 域名结构
- 格式:
www.example.com.com:顶级域名(商业机构)example:二级域名(机构名称)www:三级域名(服务器名)
- 常见顶级域名:
.com商业机构 |.org非营利组织 |.edu教育机构.gov政府机构 |.cn中国国家域名
4.3.2 DNS查询过程
- 检查本地DNS缓存 → 2. 查询本地DNS服务器 → 3. 查询根域名服务器
- 查询顶级域名服务器 → 5. 查询权威域名服务器 → 6. 返回IP地址并缓存
4.4 HTML基础(了解即可)
4.4.1 HTML文档结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网页标题</title>
</head>
<body>
<h1>一级标题</h1>
<p>段落内容</p>
</body>
</html>
4.4.2 常用HTML标签
| 标签 | 功能 | 示例 |
|---|---|---|
<h1>-<h6> |
标题标签 | <h1>一级标题</h1> |
<p> |
段落标签 | <p>这是一个段落</p> |
<a> |
超链接 | <a href="...">链接</a> |
<img> |
图像 | <img src="..." alt="..."> |
<ul>/<ol> |
无序/有序列表 | <li>列表项 |
<div>/<span> |
分区/行内分组 | 布局和样式 |
4.4.3 Web开发三要素
| 技术 | 作用 | 特点 |
|---|---|---|
| HTML | 网页结构 | 定义元素(标题、段落等) |
| CSS | 网页样式 | 设置颜色、字体、布局 |
| JavaScript | 网页交互 | 表单验证、动态内容 |
5. 计算机语言概述
5.1 计算机语言发展历史
5.1.1 机器语言
- 形式:二进制代码(0和1)
- 特点:
- 执行效率极高
- 依赖具体硬件,不可移植
- 可读性极差,难编写调试
- 现状:几乎不直接使用
5.1.2 汇编语言
- 形式:助记符(如ADD、MOV)
- 特点:
- 可读性有所提高
- 仍依赖硬件,可移植性差
- 需汇编程序翻译成机器语言
- 应用:系统底层开发、嵌入式编程
5.1.3 高级语言发展
| 时期 | 特点 | 代表语言 |
|---|---|---|
| 早期(1950-60s) | 接近自然语言,可移植性提升 | FORTRAN、COBOL、ALGOL |
| 结构化(1970-80s) | 结构化程序设计,代码模块化 | Pascal、C语言、BASIC |
| 面向对象(1980s-今) | 以对象为核心,代码复用性强 | C++、Java、Python |
| 现代脚本与专用(21世纪) | 解释型为主,针对特定领域 | JavaScript、PHP、Go、Rust |
5.2 计算机语言分类
5.2.1 按抽象层次划分
| 类型 | 特点 | 优点 | 缺点 | 代表语言 |
|---|---|---|---|---|
| 低级语言 | 直接与硬件交互 | 执行效率高,直接操作硬件 | 开发效率低,可移植性差 | 机器语言、汇编语言 |
| 高级语言 | 接近自然语言和数学逻辑 | 开发效率高,可读性好,可移植性强 | 执行效率通常较低 | C、C++、Python |
5.2.2 按执行方式划分
| 类型 | 工作方式 | 特点 | 代表语言 |
|---|---|---|---|
| 编译型 | 源代码→编译→可执行文件 | 执行速度快,可独立运行,修改需重新编译 | C、C++、Go、Rust |
| 解释型 | 解释器逐行解释执行 | 开发调试便捷,跨平台好,执行速度慢 | Python、JavaScript、PHP |
| 混合型 | 源代码→中间代码→虚拟机解释 | 兼顾跨平台和效率 | Java、C# |
重点:C++是编译型语言,需要理解编译、链接的过程。
5.2.3 按编程范式划分
| 范式 | 核心思想 | 特点 | 代表语言 |
|---|---|---|---|
| 结构化 | 函数/过程为单位,顺序/分支/循环 | 代码模块化,避免goto,适合中小程序 | C、Pascal、BASIC |
| 面向对象 | 对象为核心,封装/继承/多态 | 代码复用性强,适合大型程序 | C++、Java、Python |
| 函数式 | 函数为核心,无副作用 | 适合并行计算,代码简洁 | Lisp、Haskell |
| 脚本语言 | 语法简洁,解释执行 | 开发效率高,依赖宿主环境 | Python、JavaScript |
5.2.4 按应用领域划分
| 类型 | 应用领域 | 代表语言 |
|---|---|---|
| 通用编程语言 | 多种领域开发 | C、C++、Java、Python |
| 专用编程语言 | 特定领域优化 | SQL(数据库)、MATLAB(科学计算) |
5.3 各类语言特点总结
| 语言类型 | 代表语言 | 核心特点 | 典型应用场景 |
|---|---|---|---|
| 机器语言 | 二进制指令 | 直接执行,效率极高;可读性极差 | 早期计算机,现几乎不用 |
| 汇编语言 | x86/ARM汇编 | 接近硬件;可移植性差 | 系统底层、嵌入式 |
| 编译型高级语言 | C、C++ | 编译后执行,速度快;可移植性较好 | 操作系统、游戏、嵌入式 |
| 解释型高级语言 | Python、JavaScript | 解释执行,开发便捷;执行较慢 | Web开发、脚本、数据分析 |
| 混合型语言 | Java、C# | 编译为中间代码,虚拟机执行 | 企业级应用、移动应用 |
| 面向对象语言 | C++、Java、Python | 封装、继承、多态;适合大型程序 | 大型软件系统 |
| 函数式语言 | Haskell、Lisp | 无副作用函数,强调数学逻辑 | 人工智能、科学计算 |
| 专用语言 | SQL、MATLAB | 针对特定领域优化;通用性差 | 数据库、科学计算 |
5.4 计算机语言发展趋势
- 更高的开发效率:语法简洁,抽象层次高(Python、Go)
- 更强的跨平台性:虚拟机、容器技术(Java的“一次编写,到处运行”)
- 更好的安全性:注重内存安全、类型安全(Rust的所有权机制)
- 适应新兴领域:AI、大数据、云计算专用语言和库
- 多范式融合:单一范式→多范式发展(C++、Python支持多种范式)
6. 流程图与算法描述
6.1 流程图的基本概念
6.1.1 定义与作用
流程图是一种用标准化图形符号、箭头和文字说明来表示算法或程序执行步骤的可视化工具。
核心作用
| 作用 | 说明 | 对GESP的意义 |
|---|---|---|
| 可视化逻辑 | 将抽象算法转化为直观图形,便于理解和沟通 | 帮助初学者理解程序执行流程 |
| 梳理流程 | 编程前规划程序结构,避免逻辑漏洞 | 培养编程前的设计习惯 |
| 调试辅助 | 通过流程图定位逻辑错误 | 提升代码调试能力 |
| 标准化表达 | 统一符号,便于交流 | 标准化表示算法思想 |
重点:流程图是算法的图形化表示,是编写程序前的重要设计步骤。
6.1.2 流程图的分类
| 类型 | 描述 | 适用场景 |
|---|---|---|
| 程序流程图 | 描述程序执行步骤,包括顺序、分支、循环等结构 | GESP二级主要考察类型 |
| 系统流程图 | 描述整个系统的模块划分和数据流向 | 大型程序设计 |
| 业务流程图 | 描述实际业务处理流程 | 系统分析与设计 |
6.2 流程图的基本符号
6.2.1 常用符号及含义
| 符号形状 | 名称 | 含义与应用场景 | 示例 |
|---|---|---|---|
| ![圆角矩形] | 开始/结束框 | 表示流程的起点(标注"开始")或终点(标注"结束") | 开始、结束 |
| ![矩形] | 处理框 | 表示具体的操作或处理步骤 | sum = a + b |
| ![菱形] | 判断框 | 表示分支判断,有两个或多个出口 | x > 0 ? |
| ![平行四边形] | 输入/输出框 | 表示数据的输入或输出操作 | 输入n、输出result |
| ![箭头] | 流向线 | 表示流程的执行方向 | 连接各个符号 |
注意:判断框的出口必须标注逻辑方向(如"是"/"否"或"Y"/"N")
6.2.2 符号使用原则
- 大小适中:符号大小要合适,便于阅读
- 文字简洁:框内用简洁明了的文字(如用
i++代替"将变量i的值增加1") - 方向规范:流向线尽量从上到下、从左到右绘制
- 避免交叉:流向线尽量避免交叉,必要时用连接点
6.3 流程图的基本结构
6.3.1 顺序结构
定义
步骤按先后顺序依次执行,无分支或循环。
图示特点
各符号用流向线依次连接,形成一条直线。
示例:计算两数之和
graph TD
A[开始] --> B[输入整数a]
B --> C[输入整数b]
C --> D[sum = a + b]
D --> E[输出sum]
E --> F[结束]
// 顺序结构示例
#include <iostream>
using namespace std;
int main() {
int a, b, sum;
cin >> a; // 输入a
cin >> b; // 输入b
sum = a + b; // 计算和
cout << sum << endl; // 输出结果
return 0;
}
6.3.2 分支结构(选择结构)
定义
根据判断条件的真假,选择执行不同的分支。
分类
| 类型 | 描述 | 适用场景 |
|---|---|---|
| 双分支 | 满足条件执行分支A,否则执行分支B | 最常用 |
| 多分支 | 根据多个条件判断,选择多个分支中的一个 | 多个条件的情况 |
示例1:双分支(判断正数)
graph TD
A[开始] --> B[输入整数x]
B --> C{x > 0?}
C -->|是| D[输出"Positive"]
C -->|否| E[输出"Non-positive"]
D --> F[结束]
E --> F
// 双分支结构示例
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
if (x > 0) {
cout << "Positive" << endl;
} else {
cout << "Non-positive" << endl;
}
return 0;
}
示例2:多分支(成绩等级)
graph TD
A[开始] --> B[输入成绩score]
B --> C{score >= 90?}
C -->|是| D[输出"A"]
C -->|否| E{score >= 80?}
E -->|是| F[输出"B"]
E -->|否| G{score >= 60?}
G -->|是| H[输出"C"]
G -->|否| I[输出"D"]
D --> J[结束]
F --> J
H --> J
I --> J
// 多分支结构示例
#include <iostream>
using namespace std;
int main() {
int score;
cin >> score;
if (score >= 90) {
cout << "A" << endl;
} else if (score >= 80) {
cout << "B" << endl;
} else if (score >= 60) {
cout << "C" << endl;
} else {
cout << "D" << endl;
}
return 0;
}
重点:分支结构最终必须汇合到同一出口,避免流程发散。\
6.3.3 循环结构
定义
根据条件重复执行某段流程(循环体)。
分类
| 类型 | 描述 | 特点 | C++对应语句 |
|---|---|---|---|
| 当型循环 | 先判断条件,为真则执行循环体 | 可能一次都不执行 | while |
| 直到型循环 | 先执行循环体,再判断条件 | 至少执行一次 | do-while |
类型1:当型循环(While型)
流程图示例(打印1-5):
graph TD
A[开始] --> B[i = 1]
B --> C{i < 5?}
C -->|是| D[输出i]
D --> E[i++]
E --> C
C -->|否| F[结束]
6.4 流程图的绘制规则与技巧
6.4.1 绘制规则
| 规则 | 说明 | 示例 |
|---|---|---|
| 标准化符号 | 严格使用规定符号(判断必须用菱形) | 不能矩形替代菱形 |
| 单一入口出口 | 整个流程图有唯一的开始框,分支/循环最终汇合 | 避免多个独立出口 |
| 逻辑清晰 | 步骤顺序合理,避免不必要的跳转 | 避免从循环内直接跳到外部 |
| 文字简洁 | 框内用动词或短句 | 用i++而不是"将i加1" |
6.4.2 绘制技巧
| 技巧 | 说明 | 目的 |
|---|---|---|
| 先抽象后细化 | 先用粗线条勾勒主要步骤,再逐步细化 | 避免一开始陷入细节 |
| 避免交叉线 | 调整符号位置或使用连接点 | 提高可读性 |
| 嵌套结构缩进 | 循环体内的分支向右缩进 | 清晰区分层次 |
| 标注层次编号 | 多层嵌套时标注"循环1"、"分支2" | 便于理解复杂结构 |
6.5 流程图与代码的对应关系
6.5.1 顺序结构
流程图:A → B → C C++代码:
A; // 步骤A
B; // 步骤B
C; // 步骤C
6.5.2 分支结构
双分支
流程图:判断条件→是→A;否→B→汇合 C++代码:
if (条件) {
A; // 条件成立执行的代码
} else {
B; // 条件不成立执行的代码
}
多分支
流程图:条件1→是→A;否→条件2→是→B;否→C C++代码:
if (条件1) {
A;
} else if (条件2) {
B;
} else {
C;
}
6.5.3 循环结构
当型循环
流程图:初始化→判断条件→是→循环体→回到判断;否→退出 C++代码:
初始化;
while (条件) {
循环体;
}
直到型循环
流程图:初始化→循环体→判断条件→否→回到循环体;是→退出 C++代码:
初始化;
do {
循环体;
} while (条件); // 注意:条件为假时继续循环
第7章 ASCII编码
7.1 ASCII编码的基本概念
7.1.1 定义与作用
- 定义:ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是一套基于拉丁字母的字符编码系统,通过7位二进制数(共128种组合)表示大小写字母、数字、标点符号及控制字符。
- 作用:统一字符与二进制数值的对应关系,使计算机能够存储、传输和处理文本信息(如键盘输入、屏幕显示、文件读写等)。
7.1.2 编码规则
- 位数:基础ASCII编码使用7位二进制数(0000000 ~ 1111111),对应十进制范围0~127,共128个字符。
- 存储形式:在计算机中,ASCII字符通常用1个字节(8位)存储,最高位(第8位)为0(用于兼容扩展编码)。
- 对应关系:每个字符唯一对应一个十进制数值(如字符
A对应65,字符0对应48)。
7.2 ASCII字符的分类
根据功能和数值范围,ASCII字符可分为以下几类:
7.2.1 控制字符(十进制0~31,127)
- 定义:不可打印的字符,用于控制设备(如打印机、终端)的操作,无实际显示符号。
- 常用控制字符:
- 0 (NULL, 空字符):表示字符串结束(C/C++中
'\0')。(重点) - 10 (LF,换行):将光标移至下一行开头(
'\n')。 - 13 (CR,回车):将光标移至当前行开头(
'\r')。 - 27 (ESC):退出或取消操作。
- 127 (DEL,删除):删除光标前的字符。
- 0 (NULL, 空字符):表示字符串结束(C/C++中
7.2.2 可打印字符(十进制32~126)
- 空格字符 (32)
十进制值32,对应字符
' '(空格),用于分隔文本中的单词或字符。 - 数字字符 (48~57)
- 十进制值48对应
‘0’,49对应‘1’,...,57对应‘9’。 - 编码值连续:相邻数字的编码值连续递增(如
'5' - '0' = 5)。
- 十进制值48对应
- 大写字母 (65~90) (重点)
- 十进制值65对应
‘A’,66对应‘B’,...,90对应‘Z’。 - 编码值连续:相邻字母编码值连续(如
'C' - 'A' = 2)。
- 十进制值65对应
- 小写字母 (97~122) (重点)
- 十进制值97对应
‘a’,98对应‘b’,...,122对应‘z’。 - 编码值连续:相邻字母编码值连续(如
'd' - 'a' = 3)。 - 大小写字母转换:
小写字母编码值 = 大写字母编码值 + 32(如‘a’ = ‘A’ + 32)。
- 十进制值97对应
- 标点符号与特殊字符(其余可打印字符)
- 包括运算符(
+, -, *, /)、标点(!, ?, ;)、括号((, ), {, })等。 - 部分常用字符的编码值:
33: '!',43: '+',45: '-',61: '=',63: '?',95: '_'。
- 包括运算符(
7.3 常用 ASCII 编码值速查表
| 字符 | 十进制值 | 二进制值 | 分类 |
|---|---|---|---|
\0 |
0 | 00000000 | 控制字符(空字符) |
| `` (空格) | 32 | 00100000 | 可打印字符 |
0 |
48 | 00110000 | 数字 |
9 |
57 | 00111001 | |
A |
65 | 01000001 | 大写字母 |
Z |
90 | 01011010 | |
a |
97 | 01100001 | 小写字母 |
z |
122 | 01111010 | |
\n |
10 | 00001010 | 控制字符(换行) |
\r |
13 | 00001101 | 控制字符(回车) |
7.4 扩展 ASCII 编码
7.4.1 定义与编码规则
- 扩展ASCII编码(Extended ASCII)是对基础ASCII的扩展,使用8位二进制数(00000000 ~ 11111111)表示字符,共包含256个字符(十进制值0~255)。
- 其中0~127与基础ASCII完全一致,128~255为扩展字符集,用于补充基础ASCII未涵盖的符号。
7.4.2 扩展字符的分类(128~255)
- 拉丁扩展字符:带重音(accents)的欧洲语言字符,如
à(133)、é(130)、ñ(164)等。 - 图形符号:线条符号(如— (196))、块状符号(如■ (254)、● (183))。
- 特殊符号:货币符号(如€ (128)、£ (163)、¥ (165))、数学符号(如± (177)、× (215)、÷ (247))。
7.4.3 扩展ASCII的局限性 (重点)
- 无统一标准:不同系统(如Windows、DOS、Linux)采用的扩展ASCII表存在差异(如十进制128在Windows中表示
€,在其他系统中可能表示其他符号)。 - 跨平台兼容性差:由于标准不统一,使用扩展ASCII字符的程序在不同系统中可能显示异常,因此建议优先选择基础ASCII字符。
7.4.4 扩展ASCII编码值示例(Windows-1252标准)
| 十进制值 | 字符 | 描述 |
|---|---|---|
| 128 | € | 欧元符号 |
| 169 | © | 版权符号 |
| 174 | ® | 注册商标符号 |
| 192 | À | 带重音的大写A |
| 215 | × | 乘号 |
| 247 | ÷ | 除号 |
| 254 | ■ | 实心方块 |
7.5 ASCII编码在C/C++中的应用
7.5.1 字符与整数的转换
在C/C++中,char类型本质是8位整数,可直接与int类型相互转换(利用ASCII编码值)。(重点)
char c = 'A';
int num = c; // num = 65 ('A'的ASCII值)
char d = 97; // d = 'a' (97对应小写字母a)
7.5.2 字符判断与处理
-
判断字符类型:
// 判断是否为大写字母 bool isUpper(char c) { return c >= 'A' && c <= 'Z'; // 利用ASCII值范围 } // 判断是否为数字字符 bool isDigit(char c) { return c >= '0' && c <= '9'; } -
字符转换:
// 大写字母转小写字母 char toLower(char c) { if (c >= 'A' && c <= 'Z') { // 先判断是否为大写 return c + 32; // 利用大小写字母 ASCII 值差 32 (重点) } return c; } // 类似地,小写转大写可用 c - 32
7.5.3 字符串处理 (重点)
-
字符串以
'\0'(ASCII值0)为结束标志,用于判断字符串长度或终止遍历。// 计算字符串长度(不包含'\0') int strLength(const char* str) { int len = 0; while (str[len] != '\0') { // 当字符为'\0'时结束 len++; } return len; }
7.5.4 输入输出操作
-
用
printf/cout输出字符时,会自动根据ASCII值显示对应符号;输入时,键盘字符会被转换为ASCII值存储。char c; cin >> c; // 输入'A', c 存储 65 cout << c; // 输出'A'(65 对应的字符) printf("%d", c); // 输出 65(直接打印 ASCII 值)
7.6 ASCII 的局限与替代编码
7.6.1 局限
- 仅支持拉丁字母,无法表示中文、日文等非拉丁字符。
- 字符集规模小(基础ASCII仅128个字符),无法满足多语言文本处理需求。
- 扩展ASCII无统一标准,跨平台兼容性差。
7.6.2 常见替代编码
- Unicode:包含全球所有语言的字符,采用16位或32位编码,兼容ASCII(0~127完全一致)。在C++中可通过
wchar_t、char16_t、char32_t等类型处理。 - GBK/GB2312:中文编码标准,兼容ASCII,可表示简体中文、繁体中文、日文、韩文等字符。
第8章 循环与分支的嵌套
8.1 嵌套结构概述
在程序设计中,单一的分支或循环语句往往难以满足复杂问题的求解需求。通过将分支语句与循环语句进行嵌套组合,可以构建出更灵活、功能更强大的程序结构,用于处理多层条件判断或重复执行特定操作的场景。
8.2 分支嵌套
8.2.1 if语句的嵌套
if语句的嵌套是指在if、else if或else子句的语句块中包含其他if语句,用于处理存在多层条件判断的场景。
- 基本语法:
if(条件表达式1) {
// 语句块1
if(条件表达式2) {
// 语句块2(条件1为真且条件2为真时执行)
} else {
// 语句块3(条件1为真且条件2为假时执行)
}
} else {
// 语句块4(条件1为假时执行)
}
- 执行逻辑:
- 外层if语句先判断条件表达式1
- 若为真,进入语句块1,此时会执行内层if语句的判断
- 若条件表达式1为假,则执行else子句的语句块4,内层if语句不执行
- 示例:成绩等级判断
int score = 85;
if (score >= 60) {
cout << "及格" << endl;
if (score >= 90) {
cout << "优秀" << endl;
} else if (score >= 80) {
cout << "良好" << endl;
} else {
cout << "中等" << endl;
}
} else {
cout << "不及格" << endl;
}
// 输出结果:及格 良好
- 注意事项:
- 内层if语句必须完全包含在外层分支的语句块中,通过缩进增强代码可读性
- else子句总是与离它最近的未配对的if语句配对,必要时可通过大括号明确嵌套关系,避免逻辑混淆
8.2.2 switch语句的嵌套
switch语句的嵌套是指在某个case或default子句的语句块中包含另一个switch语句。
- 基本语法:
switch (表达式1) {
case 常量1:
// 语句块1
switch (表达式2) {
case 常量A:
// 语句块A(表达式1为常量1且表达式2为常量A时执行)
break;
default:
// 语句块B(表达式1为常量1且表达式2不匹配任何常量时执行)
}
break;
default:
// 语句块2(表达式1不匹配任何常量时执行)
}
- 示例:
int a = 1, b = 2;
switch (a) {
case 1:
printf("a=1\n");
switch (b) {
case 1:
printf("b=1\n");
break;
case 2:
printf("b=2\n");
break;
}
break;
case 2:
printf("a=2\n");
break;
}
// 输出结果:a=1 b=2
- 注意事项:
- 内层switch语句中的break仅作用于内层switch,不会跳出外层switch
- 嵌套层次不宜过多,否则会降低代码可读性
8.3 循环嵌套
8.3.1 基本概念
循环嵌套指的是在一个循环语句(for、while、do-while)的循环体中包含另一个完整的循环语句。外层循环控制内层循环的执行次数,内层循环则完成具体的重复操作。
8.3.2 for循环的嵌套
for循环的嵌套是最常用的循环嵌套形式,适合处理具有明确边界的多层重复问题(如二维数组遍历)。
- 基本语法:
for (初始化表达式1; 循环条件1; 循环后操作1) {
// 外层循环体
for (初始化表达式2; 循环条件2; 循环后操作2) {
// 内层循环体(外层循环执行一次,内层循环执行一轮)
}
}
- 执行逻辑:
- 外层循环每执行一次,内层循环会完整执行所有次数(直到内层循环条件为假)
- 外层循环变量更新,重复上述过程,直到外层循环条件为假
- 示例:打印5行5列的矩形星号图案
for (int i = 1; i <= 5; i++) { // 外层循环控制行数
for (int j = 1; j <= 5; j++) { // 内层循环控制每行星号数
cout << "* ";
}
cout << endl;
}
// 输出结果:
// * * * * *
// * * * * *
// * * * * *
// * * * * *
// * * * * *
8.3.3 while循环的嵌套
while循环的嵌套适用于循环次数不确定,但存在多层重复逻辑的场景。
- 基本语法:
初始化外层循环变量;
while (循环条件1) {
// 外层循环体
初始化内层循环变量;
while (循环条件2) {
// 内层循环体
更新内层循环变量;
}
更新外层循环变量;
}
- 示例:计算1-3的每个数的1-2次方之和
int i = 1;
while (i <= 3) {
int sum = 0;
int j = 1;
while (j <= 2) {
sum += i * j;
j++;
}
printf("%d的1-2次方之和: %d\n", i, sum);
i++;
}
// 输出结果:
// 1的1-2次方之和: 3
// 2的1-2次方之和: 6
// 3的1-2次方之和: 9
8.3.4 不同类型循环的嵌套
for循环、while循环和do-while循环可以相互嵌套,根据实际需求选择合适的组合。
- 示例:用for循环嵌套do-while循环打印三角形
for (int i = 1; i <= 3; i++) {
int j = 1;
do {
cout << "* ";
j++;
} while (j <= i);
cout << endl;
}
// 输出结果:
// *
// * *
// * * *
8.3.5 循环嵌套注意事项
- 内层循环和外层循环的循环变量应使用不同的变量名(如i和j),避免变量冲突
- 嵌套层数越多,程序执行效率可能越低,应尽量优化逻辑,减少不必要的嵌套
- 确保内层循环有明确的终止条件,避免出现无限循环
8.4 分支和循环的嵌套
分支和循环的嵌套是指在循环语句中包含分支语句,或在分支语句中包含循环语句,用于处理需要根据条件重复执行不同操作,或在特定条件下执行循环的场景。
8.4.1 循环中嵌套分支
在循环体内部包含分支语句,根据循环过程中的条件动态执行不同的操作。
- 基本语法(循环中嵌套if):
循环语句{
if(条件表达式){
// 满足条件时执行的操作
} else {
// 不满足条件时执行的操作
}
}
- 示例:计算1-10中偶数的和
int sum = 0;
for (int i = 1; i <= 10; i++) {
if(i % 2 == 0){
sum += i;
}
}
cout << "1-10中偶数的和:" << sum << endl; // 输出结果:30
8.4.2 分支中嵌套循环
在分支语句的语句块中包含循环语句,仅当满足特定条件时才执行循环操作。
- 基本语法(if中嵌套循环):
if(条件表达式){
循环语句{
// 循环执行的操作
}
} else {
// 不满足条件时的操作
}
- 示例:若输入的数大于0,则打印该数的乘法表
int n;
printf("请输入一个整数:");
scanf("%d", &n);
if(n > 0) {
for(int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
printf("%d×%d=%d ", j, i, j*i);
}
printf("\n");
}
} else {
printf("输入的数不大于0,不打印乘法表\n");
}
8.5 嵌套结构的通用注意事项
- 结构层次清晰:分支与循环的嵌套应遵循"内层结构完全包含于外层结构"的原则,通过缩进清晰展示层次关系
- 控制语句的使用:
- break语句:仅跳出当前所在的循环或switch语句,不会跳出外层循环或分支
- continue语句:仅跳过当前循环的剩余部分,不影响分支语句的执行
- 可读性与维护性:
- 复杂嵌套结构容易导致逻辑错误,编写时应逐步测试,确保每一层的逻辑正确性
- 嵌套层次不宜过深,建议不超过3层,否则应考虑重构代码
- 性能考虑:
- 避免在循环嵌套中进行不必要的复杂计算
- 尽量减少循环嵌套的层数,优化算法时间复杂度
8.6 综合应用示例
示例1:打印九九乘法表
for (int i = 1; i <= 9; i++) { // 外层循环控制行
for (int j = 1; j <= i; j++) { // 内层循环控制列
printf("%d×%d=%-2d ", j, i, i*j);
}
printf("\n");
}
示例2:判断素数
int num;
cout << "请输入一个正整数:";
cin >> num;
bool isPrime = true;
if (num <= 1) {
isPrime = false;
} else {
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
isPrime = false;
break;
}
}
}
if (isPrime) {
cout << num << "是素数" << endl;
} else {
cout << num << "不是素数" << endl;
}
第9章 常用数学函数
9.1 概述
在C++编程中,数学函数是实现数值计算和科学运算的重要工具。GESP-C++二级考试中,掌握这些常用数学函数对于解决各种计算问题至关重要。
9.1.1 头文件包含
- C语言:使用
<math.h>、<stdlib.h>和<time.h> - C++推荐:使用
<cmath>、<cstdlib>和<ctime>(位于std命名空间中) - 最佳实践:在C++中推荐使用
<cmath>头文件,以符合C++标准规范
9.2 绝对值函数
绝对值函数用于获取一个数的绝对值,根据数据类型的不同有以下几种:
9.2.1 整数绝对值函数
#include <cstdlib> // 或 <cmath>
int x = -5;
int abs_x = abs(x); // 返回 5
int abs(int x):返回整数 x 的绝对值- 示例:
abs(-5)返回5,abs(3)返回3
9.2.2 长整数绝对值函数
long labs(long x); // 返回长整数 x 的绝对值
- 示例:
labs(-100000L)返回100000L
9.2.3 浮点数绝对值函数
#include <cmath>
double x = -3.14;
double abs_x = fabs(x); // 返回 3.14
double fabs(double x):返回双精度浮点数 x 的绝对值- 示例:
fabs(-3.14)返回3.14,fabs(2.718)返回2.718
9.3 幂函数
幂函数主要用于进行幂运算和求平方根等操作。
9.3.1 幂运算函数
#include <cmath>
double result1 = pow(2.0, 3.0); // 2^3 = 8.0
double result2 = pow(10.0, 2.0); // 10^2 = 100.0
double pow(double x, double y):返回 x 的 y 次方(x^y)- 注意:当 x 为负数且 y 不是整数时,结果可能为 NaN(非数字)
9.3.2 平方根函数
#include <cmath>
double sqrt_16 = sqrt(16.0); // 返回 4.0
double sqrt_2 = sqrt(2.0); // 约返回 1.4142
double sqrt(double x):返回 x 的平方根- 重要限制:x 必须大于等于 0,否则结果未定义或返回 NaN
- 示例:
sqrt(16.0)返回4.0,sqrt(2.0)约返回1.4142
9.4 取整与四舍五入函数
9.4.1 向上取整函数
#include <cmath>
double ceil1 = ceil(3.2); // 返回 4.0
double ceil2 = ceil(-2.8); // 返回 -2.0
double ceil(double x):返回大于或等于 x 的最小整数(向上取整)- 示例:
ceil(3.2)返回4.0,ceil(-2.8)返回-2.0
9.4.2 向下取整函数
#include <cmath>
double floor1 = floor(3.8); // 返回 3.0
double floor2 = floor(-1.2); // 返回 -2.0
double floor(double x):返回小于或等于 x 的最大整数(向下取整)- 示例:
floor(3.8)返回3.0,floor(-1.2)返回-2.0
9.4.3 四舍五入函数
#include <cmath>
double round1 = round(3.2); // 返回 3.0
double round2 = round(3.6); // 返回 4.0
double round3 = round(-2.3); // 返回 -2.0
double round4 = round(-2.6); // 返回 -3.0
double round(double x):对 x 进行四舍五入,返回最接近 x 的整数- 注意:
round函数遵循"四舍六入五成双"规则(银行家舍入法)
9.5 取大取小函数
9.5.1 整数取大取小
// C++中可以使用algorithm头文件中的max/min函数
#include <algorithm>
int max_val = max(5, 8); // 返回 8
int min_val = min(5, 8); // 返回 5
max(a, b):返回两个整数 a 和 b 中的最大值min(a, b):返回两个整数 a 和 b 中的最小值
9.5.2 浮点数取大取小
#include <cmath>
double fmax_val = fmax(3.14, 2.718); // 返回 3.14
double fmin_val = fmin(3.14, 2.718); // 返回 2.718
double fmax(double a, double b):返回两个浮点数 a 和 b 中的最大值double fmin(double a, double b):返回两个浮点数 a 和 b 中的最小值- 优势:适用于浮点数,能更精准地处理浮点数比较
- 示例:
fmax(3.14, 2.718)返回3.14,fmin(-2.5, 1.8)返回-2.5
9.8 C 与 C++ 中数学函数的联系与区别
9.8.1 联系
- C++ 语言继承了 C 语言中所有的数学函数
- 函数功能和使用方式基本一致
9.8.2 区别
- 头文件不同:
- C:
<math.h>、<stdlib.h>、<time.h> - C++:
<cmath>、<cstdlib>、<ctime>
- C:
- 命名空间:
- C++ 的
<cmath>中函数通常位于std命名空间中 - 可以使用
using namespace std;或std::前缀调用
- C++ 的
- 推荐用法:
- 在 C++ 中推荐使用
<cmath>头文件,符合 C++ 标准规范 - 可以使用 C 的头文件,但不符合 C++ 最佳实践
- 在 C++ 中推荐使用
9.9 使用数学函数的注意事项
9.9.1 头文件包含
-
必须包含相应的头文件:
// C++ 推荐方式 #include <cmath> // 数学函数 #include <cstdlib> // 随机函数、abs等 #include <ctime> // 时间函数
9.9.2 数据类型匹配
- 注意参数和返回值类型:
- 大多数数学函数的参数和返回值为
double类型 - 随机函数
rand()返回int类型 - 注意类型匹配,避免精度损失
- 大多数数学函数的参数和返回值为
9.9.3 函数定义域
- 关注函数的定义域:
sqrt(x)要求 x ≥ 0pow(x, y)当 x 为负数且 y 不是整数时,结果可能为 NaN- 若超出定义域,函数行为是未定义的,可能返回错误值或导致程序异常
9.9.4 随机函数的特性
- 伪随机数:
rand()生成的是伪随机数,序列可预测 - 种子初始化:必须用
srand()初始化种子,否则默认种子为 1 - 种子相同:相同种子会产生相同的随机数序列
- 时间种子:推荐使用
srand(time(NULL))保证每次运行不同
9.9.5 精度问题
-
浮点数精度:浮点数运算可能存在精度损失
double result = sqrt(2.0); // 结果可能不是精确的 √2 -
比较浮点数:避免直接用
==比较浮点数结果// 不推荐 if (sqrt(4.0) == 2.0) { ... } // 推荐:使用容差比较 const double EPSILON = 1e-6; if (fabs(sqrt(4.0) - 2.0) < EPSILON) { ... }