Skip to content

📦08.数据结构

在编程里,我们经常需要存储和处理大量的数据。比如你想保存班上每个学生的成绩、姓名、年龄等信息,单靠一个个变量显然不现实,也不方便管理。

这时候,数据结构就派上用场了。数据结构是一种组织和管理数据的方法,它帮助我们把相关的数据组合起来,让程序更高效、更清晰。

为什么需要数据结构?

  • 高效管理大量数据:用一个数组就能存储多个学生成绩,避免写一堆单独变量。
  • 方便操作和访问:通过下标可以快速找到想要的数据。
  • 增强程序可读性和维护性:用结构体把学生的姓名、年龄、成绩等信息打包成一个整体,让代码更有逻辑,更容易理解和修改。
  • 为解决复杂问题打基础:后续学到的排序、查找、算法等,都依赖于良好的数据组织。

数组和结构体的用处

  • 数组:适合存储相同类型的多个数据,比如一组整数、多个字符、连续的分数等。它让我们能用同一个名字管理多个数据,方便循环和批量处理。
  • 结构体:适合存储不同类型的数据,比如一个学生的姓名(字符串)、年龄(整数)、成绩(浮点数)等,把这些相关信息组合成一个整体,让数据管理更直观。

🧮 1. 数组

1.1 一维数组

数组是一组相同类型数据的连续集合,用来存储多个相同类型的变量。

cpp
int nums[5];  // 定义一个可以存储5个整数的数组nums
float scores[6];// 定义一个可以存储5个浮点数的数组scores

元素指的是数组内的数据,比如int nums[5]中,分别有五个int类型的变量,它们就称为数组的元素。

1.1.1 一维数组的初始化

cpp
int nums[3] = {1, 2, 3}; //定义一个 nums 数组,并初始化其3个元素为 1,2,3
char letters[4] = {'a', 'b', 'c', '\0'};

这里初始化的意思指的是在定义一个数组的时候给其赋值,需要特别注意,只有在初始化的时候可以使用这种整体赋值的方式,在后续的使用过程中,如果需要赋值,则需要逐个赋值。

1.1.2 访问和修改数组元素

cpp
cout << nums[0];  // 访问第一个元素并打印出来
nums[1] = 10;      // 修改第二个元素为10

我们可以通过数组下标索引)来访问数组的元素,需要注意,数组的下标是从0开始的,所以第一个元素是 nums[0]

1.1.3 遍历数组

cpp
for (int i = 0; i < 3; i++) {
    cout << nums[i] << endl;
}

TIP

数组下标从0开始,最后一个元素的下标是 n-1。

1.2 二维数组

二维数组可以看作“数组的数组”,用于存储表格状的数据。

cpp
int matrix[2][3];  // 2行3列的二维数组

matrix是一个二维数组,它是一个包含两个三个元素数组的一个数组,也就是它的第一个元素和第二个元素都是一个数组,而且这个数组拥有3个元素。所以这个二维数组就可以存放2*3=6int变量。

1.2.1 二维数组的初始化

cpp
int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

1.2.2 访问二维数组元素

cpp
cout << matrix[0][1];  // 输出第一行第二列的元素,结果是2
matrix[1][2] = 10;     // 修改第二行第三列的元素为10

1.2.3 遍历二维数组

cpp
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        cout << matrix[i][j] << " ";
    }
    cout << endl;
}

遍历二维数组需要用到嵌套的for循环,这在初期阶段可能比较难以理解,可以暂时不掌握。

1.3 字符数组

字符数组用于存储字符串,注意必须以 \0 结束。

cpp
char name[10];
cin >> name;  // 输入字符串,自动添加\0
char word[] = {'H', 'i', '\0'};  // 手动赋值

TIP

'\0` 表示数字0而非字符0,它表示一个字符串到此结束了,之所以需要它,是因为内存每一个空间都是有值的,计算机在输出的时候,并不知道这个字符串到哪里结束了,所以应该约定一个用来表示结束的符号。

1.3.1 字符串函数

由于我们无法直接整体的给字符串赋值,除非在定义的时候,所有后续我们如果要复制需要单独每个元素赋值,这有一些麻烦。cstring提供了给字符串赋值的函数,方便我们一次性赋值:

cpp
#include <cstring>          //需要包含 <cstring> 库文件

strlen(name);               // 计算字符串长度(不包括\0)
strcpy(name, "Xianzi");     // 复制字符串

NOTE

C风格字符串必须以 \0 结尾,否则会导致程序错误。C风格的字符串就是字符数组,C++有新的字符串类型。

  • 字符数组错误的写法
cpp
char y[4] = {'2', '3', '2', '0'};  // 没有 \0 结尾
printf("y的值为:%s\n", y);        // 输出时会异常
  • 正确的写法:
cpp
char y[5] = {'2', '3', '2', '0', '\0'};
printf("y的值为:%s\n", y);        // 正常输出

🧾 2. 结构体

2.1 什么是结构体

结构体是自定义的数据类型,能把不同类型的数据组合成一个整体。

cpp
struct Student {
    char name[20];
    int age;
};

假设我们需要一个学生管理的系统,这样我们就可以通过结构体把一个学生的数据全都存储进去,比如名字,年龄,月考的分数等等,这样就非常方便我们不管理数据,比如可以直接查找某个结构体里面分数为95的结构体,这样我们也就找出了所有分数为95的学生。

2.2 定义结构体变量并使用

当我们定义好一个结构体后,就可以使用它来定义一个结构体变量:

cpp
//定义一个 Student 结构体
//它包含了一个可以存放20个字符的 name 字符数组,和
//一个存放年龄的 int 变量
struct Student {
    char name[20];
    int age;
};

Student s1;   //定义一个结构体

像这样我们就定义了一个机构体,接着就是进行访问,赋值。由于结构体有很多成员,所以我们使用过.来访问:

cpp
Student s1;   //定义一个结构体 s1
strcpy(s1.name, "小明"); //赋值,不能使用 s1.name = "小明 " 
s1.age = 12; // int 可以直接赋值

2.3 结构体数组

cpp
Student classA[30];  // 一个班级的学生数组

一个班级通常有很多个学生,所以我们可以将结构体作为数组元素,存放在数组中,这个结构体 classA 拥有30个 Student 结构体。

🧪 3. 小结

  • 数组是存储相同类型数据的连续空间,支持一维和二维。
  • 字符数组用于存储字符串,必须以\0结尾。
  • 结构体是把不同类型数据打包成一个整体,方便管理复杂数据。

🧠 4. 练习题

  1. 定义一个整型数组 scores,输入5个学生成绩,输出所有成绩。
  2. 输入一个包含10个数字的数组,找最大值和最小值并输出。
  3. 定义字符数组 name,用 cin 输入你的名字,输出字符串长度。
  4. 创建结构体 Student 包含姓名和年龄,定义两个学生并输出信息。
  5. 定义字符数组 word[20],手动赋值为 "Hello",循环输出每个字符。
  6. 创建整型数组 data[5],偶数位置赋1,奇数位置赋0,输出数组。
  7. 输入一个字符串,判断是否以“abc”开头,是则输出“Yes”,否则“No”。
  8. 定义结构体 Point,包含坐标 xy,输入一个点,输出坐标。
  9. 定义结构体 Rect 表示矩形,包含长和宽,计算并输出面积。
  10. 输入一个英文单词,判断是否是回文字符串(正读反读相同)。

💬 与我联系 QQ:774165314 | 微信:Yonas_Luo