1. 定义与使用
结构体定义:
------结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
结构体语法:
------struct 结构体名 {结构体成员列表};
结构体创建变量的方式有三种:
------1、struct 结构体名 变量名
------2、struct 结构体名 变量名 = {结构体成员列表}
------3、struct 结构体名 {结构体成员列表} 变量名(定义结构体时创建变量)
注意:
结构体变量在构造完成后需要进行初始化,不然会弹出警告
创建结构体变量的时候struct关键字可以省略
- 代码演示
#include <iostream>
using namespace std;
#include <string>
int main() {
// 1、结构体 结构体名 变量名;
struct student
{
string name{}; //姓名
int age{}; //年龄
int score{}; //分数
};
struct student s1;
s1.name = "小张";
s1.age = 18;
s1.score = 680;
cout << "姓名:" << s1.name << endl << "年龄:" << s1.age << endl << "分数:" << s1.score << endl;
// 2、结构体 结构体名 变量名 = {结构体成员列表};
struct student s2 = { "小刘",18,666 };
cout << "姓名:" << s2.name << endl << "年龄:" << s2.age << endl << "分数:" << s2.score << endl;
// 3、定义结构体时顺便创建变量;
struct teacher
{
string name{}; //姓名
int age{}; //年龄
int score{}; //分数
}t1;
t1.name = "何";
t1.age = 30;
t1.score = 10;
cout << "姓名:" << t1.name << endl << "年龄:" << t1.age << endl << "分数:" << t1.score << endl;
system("pause");
return 0;
}
- 输出结果
2. 结构体数组
将定义的结构体放入到数组中方便维护
结构体数组语法:
------struct 结构体名 数组名[数组长度] = {{},{},…,{}}
- 代码演示
#include <iostream>
using namespace std;
#include <string>
int main() {
// 1、定义结构体
struct student
{
string name;
int age;
int score;
};
// 2、创建结构体数组
struct student arr[3] =
{
{"小张",18,99},
{"小李",20,88},
{"小王",24,100}
};
// 3、访问结构体数组中的元素属性
arr[0].age = 33;
// 4、打印结构体数组中的元素属性
for (int i = 0; i < 3; i++)
{
cout << arr[i].name << " " << arr[i].age << " " << arr[i].score << endl;
}
system("pause");
return 0;
}
- 输出结果
3. 结构体指针
通过指针可以访问结构体中的成员
结构体指针可以通过操作符->
访问结构体中的属性
- 代码演示
#include <iostream>
using namespace std;
#include <string>
// 1、定义结构体
struct student
{
string name;
int age;
int score;
};
int main() {
// 2、创建结构体变量
struct student stu ={"小张",18,99};
// 3、创建结构体指针
struct student *p = &stu;
// 4、利用结构体指针访问结构体中的属性
p->name = "老张";
cout << "姓名: " << p->name << "年龄: " << p->age << "分数: " << p->score << endl;
system("pause");
return 0;
}
- 输出结果
4. 结构体嵌套
结构体中嵌套结构体:
------在一个结构体中的成员可以是另外一个结构体
- 代码演示
一个老师辅导一个学生,一个老师的结构体中,记录一个学生的结构体
#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() {
//创建老师结构体变量
struct teacher teach;
teach.id = 10000;
teach.name = "老王";
teach.age = 30;
teach.stu.name = "小王";
teach.stu.age = 18;
teach.stu.score = 100;
cout << "老师id: " << teach.id << "姓名: " << teach.name << "年龄: " << teach.age << endl;
cout << "学生姓名:" << teach.stu.name << "年龄: " << teach.stu.age << "分数: " << teach.stu.score << endl;
system("pause");
return 0;
}
- 输出结果
5. 结构体作函数参数
结构体可以作为函数的参数,来实现数据的传递
传递方式有两种:
------1、值传递
------2、地址传递
注意:
------若不想修改主函数中的数据,则用值传递,反之使用地址传递
。
- 代码演示
#include <iostream>
using namespace std;
#include <string>
// 定义结构体
struct student
{
string name;
int age;
int score;
};
// 1、值传递函数
void printStudent1(struct student stu)
{
stu.age = 100;
cout << "姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;
}
// 2、地址传递函数
void printStudent2(struct student * stu)
{
stu->age = 200;
cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}
int main() {
// 创建结构体变量
struct student stu = {"小张",18,100};
// 1、值传递
printStudent1(stu);
cout << "姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;
// 2、地址传递
printStudent2(&stu);
cout << "姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;
system("pause");
return 0;
}
- 输出结果
6. 结构体中const使用场景
在定义函数的时候,函数参数的传递方式为
值传递时会占用更多的内存
,而地址传递只会占用4-8个字节,因此,在数据量较大的情况下通常会采用地址传递的方式
。但是地址传递
会带来的一个问题就是会修饰实参
,从而改变主函数中的数据
。针对这个问题,可以用const这个关键字来解决,为了防止地址传递修饰实参,在指针前面加上一个const关键字(得到常量指针,只能修改指针的指向,但是不能修改指针指向内存的值)
就可以了。
- 代码演示
#include <iostream>
using namespace std;
#include <string>
// 定义结构体
struct student
{
string name;
int age;
int score;
};
// 定义一个打印函数
// 为了防止地址传递会修饰实参,在指针前面加上一个const关键字
void printstudent(const struct student *stu)
{
// stu->age = 99; //常量指针只能改变指针的指向,但是不能改变指针指向内存的值
cout << " 姓名: " << stu->name << " 年龄: " << stu->age << " 分数: " << stu->score << endl;
}
int main() {
// 创建结构体变量
struct student stu = {"老朱", 20, 100};
// 调用一个函数来打印结构体中所包含的数据
// 值传递方式会占用更多的内存,而地址传递就占用4或8个字节,因此,在数据量较大的情况下会选择用地址传递
printstudent(&stu);
// 打印一下年龄
cout << " 年龄: " << stu.age << endl;
system("pause");
return 0;
}
- 输出结果
7. 结构体使用案例
1. 案例一
- 案例描述
做毕业设计时,每名老师可以带5位学生,总共有三名老师,要求如下:老师的结构体中包含老师的姓名以及5名学生的结构体数组; 学生结构体中有学生的姓名,分数; 创建一个数组存放三名老师;通过函数给每名老师和学生的成员属性进行赋值;最终打印出老师所带的数据,以及老师所带学生的所有数据。
- 思路分析
1、创建老师、学生结构体数组;
2、定义给老师、学生结构体成员赋值的赋值函数allocateSpace(struct teacher teach_arr[], int len)
;
3、定义老师、学生结构体成员值的打印函数printInfo(struct teacher teach_arr[], int len)
;
4、依次调用赋值函数、打印函数实现案例所要求的功能;
- 代码实现
#include <iostream>
using namespace std;
#include <string>
#include <Ctime>
// 定义学生结构体
struct student
{
string s_name{}; //姓名
int s_score{}; //分数
};
// 定义教师结构体
struct teacher
{
string t_name{}; //姓名
struct student stu_arr[5]; //创建学生结构体数组
};
// 创建赋值函数
void allocateSpace(struct teacher teach_arr[], int len)
{
string name_number = "ABCDE";
for (int i = 0; i < len; i++)
{
// 给老师中的老师姓名属性赋值
teach_arr[i].t_name = "teacher_";
teach_arr[i].t_name += name_number[i]; //字符串的拼接
// 给老师中的学生的属性进行赋值
for (int j = 0; j < 5; j++)
{
// 给学生中的姓名属性赋值
teach_arr[i].stu_arr[j].s_name = "student_";
teach_arr[i].stu_arr[j].s_name += name_number[j];
// 给学生中的分数属性赋值
// 设定一个随机数来给学生的分数赋值
int random = rand() % 61 + 40; // 40~100之间的一个随机数
teach_arr[i].stu_arr[j].s_score = random;
}
}
}
//创建打印函数
void printInfo(struct teacher teach_arr[], int len)
{
for (int i = 0; i < len; i++)
{
// 打印老师的属性
cout << "老师的姓名:" << teach_arr[i].t_name << endl;
// 打印学生的属性
for (int j = 0; j < 5; j++)
{
cout << "\t学生的姓名:" << teach_arr[i].stu_arr[j].s_name << "\t学生的分数:" << teach_arr[i].stu_arr[j].s_score << endl;
}
}
}
int main() {
// 创建一个随机数种子
srand((unsigned int)time(NULL));
// 1、创建3名老师的结构体数组
struct teacher teach_arr[3];
int len = sizeof(teach_arr) / sizeof(teach_arr[0]); //教师数组长度
// 2、调用赋值函数给老师和学生赋值
allocateSpace(teach_arr , len);
// 3、调用打印函数打印结构体中的数据
printInfo(teach_arr, len);
system("pause");
return 0;
}
- 输出结果
2. 案例二
- 案例描述
设计一个英雄的结构体,包括成员的姓名,年龄,性别;
创建结构体数组,数组中存放5名英雄;通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排列,最终打印排序后的结果。 五名英雄的属性如下:
{“刘备”, 23, “男”},
{“关羽”, 22, “男”},
{“张飞”, 20, “男”},
{“赵云”, 21, “男”},
{“貂蝉”, 19, “女”}
- 思路分析
1、定义一个英雄结构体,创建一个存放5名英雄信息的结构体数组;
2、定义一个冒泡排序函数bubbleSort(struct hero h_arr[], int len)
;
3、定义英雄结构体中属性的打印函数printStruct(struct hero h_arr[], int len)
;
4、依次调用冒泡排序函数、打印函数实现案例所要求的功能;
- 代码实现
#include <iostream>
using namespace std;
#include <string>
// 定义英雄结构体
struct hero
{
string name;
int age;
string gender;
};
// 创建升序排列函数
void bubbleSort(struct hero h_arr[], int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (h_arr[j].age > h_arr[j + 1].age)
{
//此处交换的应该是每一个英雄的位置,而不是每个英雄的年龄进行交换。
struct hero temp = h_arr[j];
h_arr[j] = h_arr[j + 1];
h_arr[j + 1] = temp;
}
}
}
}
// 创建打印函数
void printStruct(struct hero h_arr[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "英雄名字:" << h_arr[i].name << "\t年龄:" << h_arr[i].age
<< "\t性别:" << h_arr[i].gender << endl;
}
}
int main() {
// 1、创建英雄结构体数组
struct hero h_arr[5] =
{
{"刘备", 23, "男"},
{"关羽", 22, "男"},
{"张飞", 20, "男"},
{"赵云", 21, "男"},
{"貂蝉", 19, "女"}
};
int len = sizeof(h_arr) / sizeof(h_arr[0]);
// 2、调用排序函数对英雄进行升序排列
bubbleSort(h_arr, len);
// 3、调用打印函数
printStruct(h_arr,len);
system("pause");
return 0;
}
- 输出结果