【C++】C++基础知识(八)---结构体

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;
}

  • 输出结果
    在这里插入图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值