1 概述
1.1 案例介绍
在现代软件开发中,数据结构的选择对程序的性能和可维护性有着至关重大的影响。数组和链表作为两种最基本的数据结构,分别适用于不同的场景。理解它们的特性和优劣,能够协助开发者在实际项目中做出更合理的技术选型,从而优化系统性能。
在C语言中,数组是高效处理批量数据的基石。其连续内存结构直接映射硬件特性,通过下标实现O(1)时间复杂度的随机访问,为算法(如排序、搜索)和底层系统开发(操作系统内核表、嵌入式寄存器映射)提供了不可替代的性能优势。
本案例相关实验将在华为云开发者空间云主机进行,开发者空间云主机为开发者提供了高效稳定的云资源,确保用户的数据安全。云主机当前已适配完整的C/C++开发环境,支持Visual Studio Code等多种IDE工具安装调测。
1.2 适用对象
- 个人开发者
- 高校学生
1.3 案例时间
本案例总时长预计40分钟。
1.4 案例流程

说明:
- 开通开发者空间,搭建C/C++开发环境。
- 打开VS Code,编写代码运行程序。
最新案例动态,请查阅《【数组与链表】数组的基本演绎法与排序“大乱斗”》「链接」。小伙伴快来领取华为开发者空间进行实操吧!
1.5 资源总览
本案例预计花费总计0元。
|
资源名称 |
规格 |
单价(元) |
时长(分钟) |
|
开发者空间-云主机 |
4vCPUs | 8GB | ARM | Ubuntu | Ubuntu 24.04 Server定制版 |
免费 |
40 |
|
VS Code |
1.97.2 |
免费 |
40 |
2 配置实验环境
2.1 开发者空间配置
面向广大开发者群体,华为开发者空间提供一个随时访问的“开发桌面云主机”、丰富的“预配置工具集合”和灵活使用的“场景化资源池”,开发者开箱即用,快速体验华为根技术和资源。
如果还没有领取开发者空间云主机,可以参考免费领取云主机文档领取。
领取云主机后可以直接进入华为开发者空间工作台界面,点击打开云主机 > 进入桌面连接云主机。


2.2 配置实验环境
参考案例中心《基于开发者空间,定制C&C++开发环境云主机镜像》“2. 实验环境搭建”、“3. VS Code安装部署”章节完成开发环境、VS code及插件安装。

3 数组的基本操作
3.1 数组基础概念
数组是一组连续内存空间中存储的一样类型数据元素的集合。
数组的声明与访问,具体代码操作如下:
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <iostream>
using namespace std;
int main() {
// 数组声明与初始化
// 声明一个包含5个整数的数组
int numbers[5];
// 声明并初始化
int primes[] = {2, 3, 5, 7, 11};
// 访问数组元素
numbers[0] = 10; // 第一个元素的索引是0
numbers[4] = 50; // 最后一个元素的索引是4
printf("数组大小:%ld字节
", sizeof(numbers));
printf("元素个数:%ld
", sizeof(numbers)/sizeof(numbers[0]));
printf("数组地址:%p
", (void*)numbers);
printf("第一个元素地址:%p
", (void*)&numbers[0]);
printf("数组第一个元素: %d
", primes[0]);
printf("数组最后一个元素: %d
", primes[4]);
return 0;
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

3.2 一维数组操作
在C语言中,一维数组是一种基础数据结构,用于在连续内存空间中存储一样类型的多个元素。对一维数组的操作包括数组的最大值、数组最小值、数组平均值、数组反转和数组排序等。
具体代码操作如下:
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <iostream>
using namespace std;
// 函数声明
void printArray(int arr[], int size);
void reverseArray(int arr[], int size);
int findMax(int arr[], int size);
int findMin(int arr[], int size);
float calculateAverage(int arr[], int size);
void bubbleSort(int arr[], int size);
int main() {
int arr[] = {8, 3, 6, 2, 9, 1, 4, 7, 5};
int size = sizeof(arr)/sizeof(arr[0]);
printf("原始数组:");
printArray(arr, size);
printf("数组反转:");
reverseArray(arr, size);
printArray(arr, size);
printf("最大值:%d
", findMax(arr, size));
printf("最小值:%d
", findMin(arr, size));
printf("平均值:%.2f
", calculateAverage(arr, size));
printf("排序后:");
bubbleSort(arr, size);
printArray(arr, size);
return 0;
}
// 打印数组
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("
");
}
// 反转数组
void reverseArray(int arr[], int size) {
for (int i = 0; i < size/2; i++) {
int temp = arr[i];
arr[i] = arr[size-1-i];
arr[size-1-i] = temp;
}
}
// 查找最大值
int findMax(int arr[], int size) {
int max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 查找最小值
int findMin(int arr[], int size) {
int min = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
// 计算平均值
float calculateAverage(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return (float)sum / size;
}
// 冒泡排序
void bubbleSort(int arr[], int size) {
for (int i = 0; i < size-1; i++) {
for (int j = 0; j < size-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

3.3 二维数组操作
在C语言中,二维数组本质上是“数组的数组”,可视为由行和列组成的表格结构。对二维数组的操作包括打印二维数组、二维数组元素访问、遍历二维数组。
具体代码操作如下:
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printArray2(int *arr, int rows, int cols);
int main() {
int matrixA[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
printf("矩阵A:
");
printArray2(&matrixA[0][0], 2, 3);
// 二维数组元素访问
// 修改第2行第3列元素(索引从0开始)
matrixA[1][2] = 10;
// 读取第1行第2列元素(val=2)
int val = matrixA[0][1];
printf("读取第1行第2列元素: %d
", val);
printArray2(&matrixA[0][0], 2, 3);
//遍历二维数组
printf("遍历二维数组:
");
for(int i=0; i<2; i++) {
for(int j=0; j<3; j++) {
printf("%d ", matrixA[i][j]);
}
printf("
");
}
return 0;
}
void printArray2(int *arr, int rows, int cols) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
// 计算元素位置:当前行首地址 + 列偏移
printf("%2d ", *(arr + i * cols + j));
}
printf("
");
}
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

3.4 字符数组与字符串
字符数组:
在C语言中,字符数组是存储字符序列(包括字符串)的基本结构。它既是普通数组的特例(元素类型为char),也是表明字符串的基础。字符数组的操作包括访问元素、修改元素、遍历元素。
具体代码操作如下:
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char letters[5] = {'a','b','c','d','e'};
// 访问元素
char first = letters[0];
printf("字符数组第一个元素:%c ",first);
printf("
");
// 修改元素
// 数组变为 {'a','z','c','d','e'}
letters[1] = 'z';
size_t len = sizeof(letters);
printf("修改后的字符数组元素为:");
for (int i = 0; i < len; i++) {
printf("%c ", letters[i]);
}
printf("
");
// 遍历
printf("遍历字符数组元素:");
for (int i = 0; i < sizeof(letters); i++) {
printf("%c ", letters[i]);
}
printf("
");
// 添加终止符,成为字符串
letters[5] = '';
// 目前可以安全使用字符串函数
printf("字符数组转换成字符串:%s", letters);
printf("
");
return 0;
}
void printArray2(int *arr, int rows, int cols) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
// 计算元素位置:当前行首地址 + 列偏移
printf("%2d ", *(arr + i * cols + j));
}
printf("
");
}
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

字符串:
字符串的复制、连接、比较等。
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
// 定义字符串
// 自动计算长度(12字节:11字符+1'')
char s1[] = "Hello World";
printf("字符串s1: %s
", s1);
// 字符串长度
int len = strlen("Hello");
printf("字符串s1的长度: %d
", len);
// 字符串的复制
char source[] = "Hello C";
char dest[20];
// 安全复制
strncpy(dest, source, sizeof(dest) - 1);
// 确保终止
dest[sizeof(dest) - 1] = '';
printf("复制字符串dest: %s
", dest);
// 字符串连接
char str[50] = "你好,";
// 安全连接
strncat(str, "C语言!", sizeof(str) - strlen(str) - 1);
printf("复制字符串str: %s
", str);
// 字符串比较
int result = strcmp("apple", "banana");
printf("字符串比较result: %d
", result);
result = strcmp("apple", "apple");
printf("字符串比较result: %d
", result);
result = strcmp("banana", "apple");
printf("字符串比较result: %d
", result);
return 0;
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

4 综合案例:学生成绩管理系统
4.1 功能需求分析
学生成绩管理系统设计功能如下:
- 打印出所有学生的考试成绩;
- 计算出全班学生的平均分和最高分;
- 所有学生的平均分按照降序排列;
- 统计学生成绩分布情况(优秀、良好、中等、及格、不及格)。
4.2 代码实现及验证
Step1:复制以下代码,替换main.cpp文件中的代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 函数声明
void studentManagementSystem();
int main() {
printf("
=== 综合案例:学生成绩管理系统 ===
");
studentManagementSystem();
return 0;
}
// 综合案例:学生成绩管理系统
void studentManagementSystem() {
#define MAX_STUDENTS 100
#define MAX_NAME_LENGTH 50
typedef struct {
int id;
char name[MAX_NAME_LENGTH];
float scores[3]; // 三门课程的成绩
float average;
} Student;
Student students[MAX_STUDENTS];
int count = 0;
printf("
--- 学生成绩管理系统 ---
");
// 添加学生数据
students[count++] = (Student){1, "张三", {85, 90, 78}};
students[count++] = (Student){2, "李四", {92, 88, 95}};
students[count++] = (Student){3, "王五", {76, 85, 80}};
// 计算平均分
for (int i = 0; i < count; i++) {
float sum = 0;
for (int j = 0; j < 3; j++) {
sum += students[i].scores[j];
}
students[i].average = sum / 3.0;
}
// 打印学生成绩
printf("
%-5s %-10s %-8s %-8s %-8s %-8s
",
"ID", "姓名", "成绩1", "成绩2", "成绩3", "平均分");
printf("------------------------------------------------
");
for (int i = 0; i < count; i++) {
printf("%-5d %-10s %-8.1f %-8.1f %-8.1f %-8.1f
",
students[i].id,
students[i].name,
students[i].scores[0],
students[i].scores[1],
students[i].scores[2],
students[i].average);
}
// 查找最高分学生
int maxIndex = 0;
for (int i = 1; i < count; i++) {
if (students[i].average > students[maxIndex].average) {
maxIndex = i;
}
}
printf("
最高分学生: %s (平均分: %.1f)
",
students[maxIndex].name, students[maxIndex].average);
// 按平均分排序
for (int i = 0; i < count-1; i++) {
for (int j = 0; j < count-i-1; j++) {
if (students[j].average < students[j+1].average) {
Student temp = students[j];
students[j] = students[j+1];
students[j+1] = temp;
}
}
}
// 打印排序结果
printf("
按平均分降序排列:
");
printf("%-5s %-10s %-8s
", "ID", "姓名", "平均分");
printf("-----------------------
");
for (int i = 0; i < count; i++) {
printf("%-5d %-10s %-8.1f
",
students[i].id, students[i].name, students[i].average);
}
// 统计分数分布
int distribution[5] = {0}; // 0-59, 60-69, 70-79, 80-89, 90-100
for (int i = 0; i < count; i++) {
for (int j = 0; j < 3; j++) {
int score = (int)students[i].scores[j];
if (score < 60) distribution[0]++;
else if (score < 70) distribution[1]++;
else if (score < 80) distribution[2]++;
else if (score < 90) distribution[3]++;
else distribution[4]++;
}
}
printf("
分数分布统计:
");
printf("不及格(<60): %d
", distribution[0]);
printf("及格(60-69): %d
", distribution[1]);
printf("中等(70-79): %d
", distribution[2]);
printf("良好(80-89): %d
", distribution[3]);
printf("优秀(90-100): %d
", distribution[4]);
}
Step2:点击编辑器左上角运行按钮直接运行,Terminal窗口可以看到打印内容。

打印内容文本显示:
=== 综合案例:学生成绩管理系统 ===
--- 学生成绩管理系统 ---
ID 姓名 成绩1 成绩2 成绩3 平均分
------------------------------------------------
1 张三 85.0 90.0 78.0 84.3
2 李四 92.0 88.0 95.0 91.7
3 王五 76.0 85.0 80.0 80.3
最高分学生: 李四 (平均分: 91.7)
按平均分降序排列:
ID 姓名 平均分
-----------------------
2 李四 91.7
1 张三 84.3
3 王五 80.3
分数分布统计:
不及格(<60): 0
及格(60-69): 0
中等(70-79): 2
良好(80-89): 4
优秀(90-100): 3
打印内容截图:

至此,数组的基本演绎法与排序“大乱斗”案例已全部完成。


