📋第六章知识体系总览
- 数组的概念与意义
- 一维数组的定义与初始化
- 数组元素的引用与遍历
- 二维数组(矩阵)
- 字符数组与字符串
- 字符串处理函数
- 冒泡排序 / 选择排序
- 顺序查找 / 折半查找
💡 核心思想:数组是同类型数据的有序集合,在内存中连续存放。
下标从
0 开始,越界访问是常见 Bug 来源,务必注意!
📌 数组变量的意义
为什么需要数组?
📌 集中管理:假设要存储 100 个学生的成绩,用
📌 批量处理:结合循环,数组可以用
📌 内存连续:数组元素在内存中紧密排列,CPU 缓存命中率高,遍历效率远高于分散的变量。
📌 集中管理:假设要存储 100 个学生的成绩,用
int s1,s2,...,s100 需要 100 个变量名;而用 int score[100] 只需一个名字 + 下标,代码更简洁。📌 批量处理:结合循环,数组可以用
for 循环批量访问(如计算平均分、找最大值),而普通变量只能逐个单独操作。📌 内存连续:数组元素在内存中紧密排列,CPU 缓存命中率高,遍历效率远高于分散的变量。
🗺️本章学习路线图
① 概念
什么是数组
什么是数组
② 定义
类型 名[长度]
类型 名[长度]
③ 初始化
{ } 赋值
{ } 赋值
④ 引用
a[i] 访问
a[i] 访问
⑤ 算法
排序/查找
排序/查找
⑥ 字符串
字符数组
字符数组
⚡ 学习建议:按顶部标签页顺序逐节学习,每节均有可交互的动画演示,
学完后务必完成各节「随堂测验」!
✏️随堂小测验 — 章节概览
🔢一维数组的定义与初始化
/* 定义格式:类型符 数组名[常量表达式]; */
int a[5]; // 定义 5 个 int 型元素的数组
float score[10]; // 定义 10 个 float 型元素的数组
/* 初始化示例 */
int b[5] = {10, 20, 30, 40, 50};
int c[5] = {1, 2}; // 其余元素自动置 0 → {1,2,0,0,0}
int d[] = {3, 6, 9, 12, 15}; // 长度由初值个数决定,为 5
⚠️ 注意:数组下标从 0 开始,最大合法下标为 长度-1。
a[5] 的合法范围是 a[0] ~ a[4],访问 a[5] 是越界!
🏗️内存布局可视化
点击「生成数组」随机填充 5 元素数组,再点击任意格子高亮对应内存地址:
点击上方数组格子,查看元素的内存地址和值。
🔄数组遍历演示
用 for 循环逐个访问 5 元素数组,光标会逐格扫描:
int a[5] = {15, 42, 8, 73, 51};
for (int i = 0; i < 5; i++)
printf("a[%d] = %d\n", i, a[i]);
准备就绪,点击「开始遍历」演示 for 循环扫描过程。
✏️随堂小测验 — 一维数组
🧮二维数组的定义与存储
/* 定义:类型符 数组名[行数][列数]; */
int a[3][4]; // 3行4列,共12个元素
/* 初始化 —— 按行分组 */
int b[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
/* 访问元素 */
printf("%d", b[1][2]); // 输出第2行第3列 = 7
📌 二维数组在内存中按行存放:先存第0行,再存第1行……
a[i][j] 的地址 = 基址 + (i × 列数 + j) × sizeof(元素类型)
🖥️矩阵可视化演示
点击格子高亮;点击「行序遍历」查看内存顺序:
点击矩阵中的格子,或使用按钮演示遍历过程。
📐矩阵转置
/* 将矩阵 a 转置后存入 b */
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
b[j][i] = a[i][j];
原矩阵 A
→
转置矩阵 B
点击「执行转置」查看动画效果。
✏️随堂小测验 — 二维数组
📝字符数组与字符串
/* 字符数组定义 */
char s1[6] = {'H','e','l','l','o','\0'};
char s2[6] = "Hello"; // 等效写法,自动加 '\0'
/* 常用字符串函数(#include )*/
strlen(s) // 字符串长度(不含 '\0')
strcpy(dst, src) // 拷贝
strcat(s1, s2) // 拼接
strcmp(s1, s2) // 比较(返回 0 表示相等)
🔑 关键:C语言字符串以 \0(空字符)结尾。
char s[5]="Hello" 只能存4个字符,因为最后必须留位置给 '\0'!
🔬字符串内存结构演示
选择一个字符串,观察每个字符的存储情况(包括结尾的 \0)。
🔧字符串函数交互练习
选择操作,实时查看函数执行结果。
✏️随堂小测验 — 字符数组
⚙️排序算法演示
选择排序算法,观察 5 元素数组的逐步排序过程:
选择一种排序方式,点击按钮开始演示。
📄冒泡排序代码
void bubbleSort(int a[], int n) {
int i, j, temp;
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-1-i; j++) {
if (a[j] > a[j+1]) { // 相邻两数比较
temp = a[j]; // 三步交换
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
🕐 复杂度:时间复杂度 O(n²),空间复杂度 O(1)。
每轮外层循环后,最大值"冒泡"到末尾,已排序区域逐渐扩大。
📄选择排序代码
void selectionSort(int a[], int n) {
int i, j, minIdx, temp;
for (i = 0; i < n-1; i++) {
minIdx = i;
for (j = i+1; j < n; j++)
if (a[j] < a[minIdx]) minIdx = j;
temp = a[i]; a[i] = a[minIdx]; a[minIdx] = temp;
}
}
✏️随堂小测验 — 排序算法
🔍顺序查找
int seqSearch(int a[], int n, int key) {
for (int i = 0; i < n; i++)
if (a[i] == key) return i; // 找到,返回下标
return -1; // 未找到,返回 -1
}
填入要查找的值,点击「开始查找」观察逐个比较的过程。
⚡折半查找(二分查找)
✅ 前提:数组必须是有序数组!每次比较可排除一半数据,效率远高于顺序查找。
时间复杂度 O(log n)。
int binarySearch(int a[], int n, int key) {
int low = 0, high = n-1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] == key) return mid;
else if (a[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
填入要查找的值,观察折半区间的收缩过程。
✏️随堂小测验 — 查找算法
🧠随堂测验 — 第六章数组
第 1 题 / 共 8 题
得分:0