doc/docs/CPlusPlus-main/16_C++的结构体.md
sairate fa9377e4ae docs(book): 添加现代 C++教程及相关代码
- 新增现代 C++ 教程的 Preface 章节,包括英文和中文版本
- 添加 C++ Primer 练习代码
- 新增 Learn C++ 教程的 C++ 开发简介章节
- 添加头文件解析文档
- 更新 mkdocs.yml,包含新教程的目录结构
- 修改项目设置,使用 Python 3.10环境
2025-07-08 09:52:45 +08:00

675 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# C++的结构体
# 1. 结构体
① 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
② 语法struct 结构体名 { 结构体成员列表 }
③ 通过结构体创建变量的方式有三种:
1. struct 结构体名 变量名
2. struct 结构体名 变量名 = { 成员1值成员2值 }
3. 定义结构体时顺便创建变量
④ 结构体变量利用点.访问成员
```python
#include <iostream>
using namespace std;
#include <string>
//自定义数据类型一些类型的集合组成一个类型
//语法 struct 类型名称 { 成员列表 }
//结构体定义的时候struct关键字不能省略
//1创建学生数据类型学生包括(姓名年龄分数)
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//2.1 struct Student s1 s1类似结构体的实例值类似变量赋值int a = 10 属性 变量 变量值
//结构体创建的时候struct 关键字可以省略上面结构体定义的时候 struct 可以省略
struct Student s1;
//给s1属性赋值通过点.访问结构体变量中的属性
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数:" << s1.score << endl;
//2.2 struct Student s2 = { ... }
struct Student s2 = { "李四",19,80 };
cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数:" << s2.score << endl;
system("pause");
return 0;
}
```
运行结果:
- 姓名:张三年龄:18分数100
- 姓名:李四年龄:19分数80
- 请按任意键继续. . .
```python
#include <iostream>
using namespace std;
#include <string>
//自定义数据类型一些类型的集合组成一个类型
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
}s3; //2.3 创建结构体的时候顺便创建个结构体变量
int main()
{
//2.3
s3.name = "王五";
s3.age = 20;
s3.score = 60;
cout << "姓名:" << s3.name << "年龄:" << s3.age << "分数:" << s3.score << endl;
system("pause");
return 0;
}
```
运行结果:
- 姓名:王五年龄:20分数60
- 请按任意键继续. . .
## 1.1 结构体定义和使用
① 作用:将自定义的结构体放入到数组中方便维护。
② 语法struct 结构体名 数组名[元素个数] = { {},{},...,{} }
```python
#include <iostream>
using namespace std;
#include <string>
//自定义数据类型一些类型的集合组成一个类型
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//2创建结构体数组
struct Student stuArray[3] =
{
{"张三",18,100},
{"李四",28,99},
{"王五",38,66}
};
//3给结构体数组中的元素赋值
stuArray[2].name = "赵六";
stuArray[2].age = 80;
stuArray[2].score = 60;
//4遍历结构体数组
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl;
}
system("pause");
return 0;
}
```
运行结果:
- 姓名张三年龄18分数100
- 姓名李四年龄28分数99
- 姓名赵六年龄80分数60
- 请按任意键继续. . .
## 1.2 结构体数组
① 作用:将自定义的结构体放入到数组中方便维护。
② 语法struct 结构体名 数组名[元素个数] = { {},{},...,{} }
```python
#include <iostream>
using namespace std;
#include <string>
//自定义数据类型一些类型的集合组成一个类型
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//2创建结构体数组
struct Student stuArray[3] =
{
{"张三",18,100},
{"李四",28,99},
{"王五",38,66}
};
//3给结构体数组中的元素赋值
stuArray[2].name = "赵六";
stuArray[2].age = 80;
stuArray[2].score = 60;
//4遍历结构体数组
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl;
}
system("pause");
return 0;
}
```
运行结果:
- 姓名张三年龄18分数100
- 姓名李四年龄28分数99
- 姓名赵六年龄80分数60
- 请按任意键继续. . .
## 1.3 结构体指针
① 作用:通过指针访问结构体中的成员。
② 利用操作符 · > 可以通过结构体指针访问结构体属性。
```python
#include <iostream>
using namespace std;
#include <string>
//结构体指针
//定义学生结构体
struct Student
{
string name; //姓名
int age; //年龄
int score; //分数
};
int main()
{
// 1创建学生结构体变量这里的 struct 可以省略
struct Student s = { "张三",18,100 };
//2通过指针指向结构体变量
struct Student* p = &s; //对s取地址 tudent * p 类似 int * p这里的 struct 可以省略
//3通过指针访问结构体变量中的数据
//通过结构体指针 访问结构体中的属性需要利用'->'
cout << "姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
system("pause");
return 0;
}
```
运行结果:
- 姓名张三年龄18分数100
- 请按任意键继续. . .
## 1.4 结构体嵌套结构体
① 结构体中的成员可以是另一个结构体。
```python
#include <iostream>
using namespace std;
#include <string>
//因为老师的结构体里有学生的结构体所以学生结构体要在老师结构体前面先定义
//定义学生结构体
struct student
{
string name; //姓名
int age; //年龄
int score; //分数
};
//定义老师结构体
struct teacher
{
int id; //教师编号
string name; //教师姓名
int age; //年龄
struct student stu; //学生结构体
};
int main()
{
//结构体嵌套结构体
//创建老师
teacher t;
t.id = 10000;
t.name = "老王";
t.age = 50;
t.stu.name = "小王";
t.stu.age = 20;
t.stu.score = 60;
cout << "老师姓名:" << t.name << "老师编号:" << t.id << "老师年龄:" << t.age
<< "老师辅导的学生姓名:" << t.stu.name << "学生年龄:" << t.stu.age
<< "学生考试分数:" << t.stu.score << endl;
system("pause");
return 0;
}
```
运行结果:
- 老师姓名:老王 老师编号10000 老师年龄50 老师辅导的学生姓名:小王 学生年龄20 学生考试分数60
- 请按任意键继续. . .
## 1.5 结构体做函数参数
① 作用:将结构体作为参数向函数中传递,传递方式有两种。
② 传递方式有两种:
1. 值传递
2. 地址传递
```python
#include <iostream>
using namespace std;
#include <string>
//定义学生结构体
struct student
{
string name; //姓名
int age; //年龄
int score; //分数
};
//定义老师结构体
struct teacher
{
int id; //教师编号
string name; //教师姓名
int age; //年龄
struct student stu; //学生结构体
};
//打印学生信息的函数
//1值传递
void printStudent1(struct student s)
{
cout << "子函数 值传递前 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
s.age = 100;
}
//2地址传递
void printStudent2(struct student* p)
{
cout << "子函数 地址传递前 姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
p->score = 90;
}
int main()
{
//结构体做函数参数
//将学生传入到一个参数中打印学生身上的所有信息
//创建结构体变量
struct student s;
s.name = "张三";
s.age = 20;
s.score = 85;
cout << "main函数 传递前 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
printStudent1(s);
cout << "子函数 值传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
printStudent2(&s);
cout << "子函数 地址传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
cout << "main函数 传递后 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
system("pause");
return 0;
}
```
运行结果:
- main函数 传递前 姓名张三年龄20分数85
- 子函数 值传递前 姓名张三年龄20分数85
- 子函数 值传递后 姓名张三年龄20分数85
- 子函数 地址传递前 姓名张三年龄20分数85
- 子函数 地址传递后 姓名张三年龄20分数90
- main函数 传递后 姓名张三年龄20分数90
- 请按任意键继续. . .
## 1.6 结构体中const使用
① 作用const来防止误操作。
```python
#include <iostream>
using namespace std;
#include <string>
//const 的使用场景
struct student
{
//姓名
string name;
//年龄
int age;
//分数
int score;
};
//将函数中形参设置为指针用地址传递而不是值传递可以减少内存空间而且不会复制新的副本
//值传递需要复制新的副本如果有成千上万个学生调用结构体会复制成千上个副本
void printStudents(const student* s)
{
s->age = 150; //报错因为假如const之后一旦有修改的操作就会报错可以防止我们的误操作
cout << "姓名:" << s->name << "年龄:" << s->age << "分数:" << s->score << endl;
}
int main()
{
//创建结构体变量
struct student s = { "张三",15,70 };
//通过函数打印结构体变量信息
printStudents(&s);
cout << "main中张三年龄为" << s.age << endl;
system("pause");
return 0;
}
```
## 1.7 结构体案例(一)
案例描述学校正在做毕设项目每名老师带领5个学生总共有3名老师需求如下设计学生和老师的结构体其中在老师的结构体中有老师姓名和一个存放5名学生的数组作为成员学生的成员有姓名、考试分数、创建数组存放3名老师通过函数给每个老师及所带的学生赋值。最终打印出老师数据以及老师所带的学生数据。
```python
#include <iostream>
using namespace std;
#include <string>
#include <Ctime>
//学生结构体定义
struct Student
{
//姓名
string sName;
//学生数组
int score;
};
//老师结构体
struct Teacher
{
//姓名
string tName;
//学生数组
struct Student sArray[5];
};
//给老师和学生赋值的函数
void allocateSpace(struct Teacher tArray[], int len) //接收数组的两种方式一用指针二用数组名 struct Teacher tArray[]
{
string nameSeed = "ABCDE";
//给老师开始赋值
for (int i = 0; i < len; i++)
{
tArray[i].tName = "Teacher_";
tArray[i].tName += nameSeed[i];
//通过循环给每名老师所带的学生赋值
for (int j = 0; j < 5; j++)
{
tArray[i].sArray[j].sName = "Student_";
tArray[i].sArray[j].sName += nameSeed[j];
int random = rand() % 61 + 40; // 40 ~ 100
tArray[i].sArray[j].score = random; //
}
}
}
//打印所有信息
void printInfo(struct Teacher tArray[], int len)
{
for (int i = 0;i<len;i++)
{
cout << "老师姓名:" << tArray[i].tName << endl;
for (int j = 0; j < 5; j++)
{
cout << "\t学生姓名:" << tArray[i].sArray[j].sName
<< " 考试分数:" << tArray[i].sArray[j].score << endl;
}
}
}
int main()
{
//随机数种子
srand((unsigned int)time(NULL));
//1创建3名老师的数组
struct Teacher tArray[3];
//2通过函数给3名老师的信息赋值并给老师带的学生信息赋值
int len = sizeof(tArray) / sizeof(tArray[0]);
allocateSpace(tArray, len);
//3打印所有老师及所带的学生信息
printInfo(tArray, len);
system("pause");
return 0;
}
```
```python
运行结果
老师姓名Teacher_A
学生姓名Student_A 考试分数81
学生姓名Student_B 考试分数85
学生姓名Student_C 考试分数91
学生姓名Student_D 考试分数66
学生姓名Student_E 考试分数55
老师姓名Teacher_B
学生姓名Student_A 考试分数87
学生姓名Student_B 考试分数50
学生姓名Student_C 考试分数57
学生姓名Student_D 考试分数40
学生姓名Student_E 考试分数43
老师姓名Teacher_C
学生姓名Student_A 考试分数72
学生姓名Student_B 考试分数64
学生姓名Student_C 考试分数80
学生姓名Student_D 考试分数92
学生姓名Student_E 考试分数58
请按任意键继续. . .
```
## 1.8 结构体案例(二)
案例描述设计一个英雄的结构体包括成员姓名年龄性别创建结构体数组数组中存放5名英雄。通过冒泡排序算法将数组中英雄按照年龄进行升序排序最终打印排序后的结果。
五名英雄信息如下:
- {"刘备",23,"男"}
- {"关羽",22,"男"}
- {"张飞",20,"男"}
- {"赵云",21,"女"}
- {"貂蝉",19,"女"}
```python
#include <iostream>
using namespace std;
//1设计英雄结构体
struct Hero
{
//姓名
string name;
//年龄
int age;
//性别
string sex;
};
//冒泡排序实现年龄升序排列
void bubbleSort(struct Hero heroArray[], int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
//如果j下标的年龄大于j+1下标的元素的年龄交换两个元素
if (heroArray[j].age > heroArray[j + 1].age)
{
struct Hero temp = heroArray[j]; //创建一个临时结构体变量
heroArray[j] = heroArray[j + 1];
heroArray[j + 1] = temp;
}
}
}
}
void printHero(struct Hero heroArray[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
<< " 性别:" << heroArray[i].sex << endl;
}
}
int main()
{
//2创建数组存放5名英雄
struct Hero heroArray[5] =
{
{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"女"},
{"貂蝉",19,"女"},
};
int len = sizeof(heroArray) / sizeof(heroArray[0]);
cout << "排序前的打印结果" << endl;
for (int i = 0; i < len; i++)
{
cout << "姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
<< " 性别:" << heroArray[i].sex << endl;
}
//3对数组进行排序按照年龄进行升序排序
bubbleSort(heroArray, len);
//4将排序后结果打印输出
cout << "排序后的打印结果" << endl;
printHero(heroArray,len);
system("pause");
return 0;
}
```
运行结果:
- 排序前的打印结果
- 姓名:刘备 年龄23 性别:男
- 姓名:关羽 年龄22 性别:男
- 姓名:张飞 年龄20 性别:男
- 姓名:赵云 年龄21 性别:女
- 姓名:貂蝉 年龄19 性别:女
- 排序后的打印结果
- 姓名:貂蝉 年龄19 性别:女
- 姓名:张飞 年龄20 性别:男
- 姓名:赵云 年龄21 性别:女
- 姓名:关羽 年龄22 性别:男
- 姓名:刘备 年龄23 性别:男
- 请按任意键继续. . .