C++阶段01笔记08【结构体(基本概念、定义与使用、数组、指针、嵌套、const使用)】

C++| 匠心之作 从0到1入门学编程【视频+课件+笔记+源码】

目录

8 结构体

8.1 结构体基本概念

8.2 结构体定义和使用

示例

8.3 结构体数组

示例

8.4 结构体指针

示例

8.5 结构体嵌套结构体

示例

8.6 结构体做函数参数

示例

8.7 结构体中const使用场景

示例

8.8 结构体案例

8.8.1 案例1

8.8.2 案例2


8 结构体

8.1 结构体基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。

C++内置数据类型:int、float、double、string、char ...

8.2 结构体定义和使用

语法:struct 结构体名 { 结构体成员列表 };

通过结构体创建变量的方式有3种:

  1. struct 结构体名 变量名

  2. struct 结构体名 变量名 = { 成员1值 , 成员2值...}

  3. 定义结构体时,顺便创建变量

示例

  

#include <iostream>
#include <string>
using namespace std;

//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些数据类型集合组成的一个类型(其实就是内置数据类型的集合)。
//语法:struct 类型名称 { 成员列表 }

//结构体定义
struct student //结构体名称-见名知意
{
	//成员列表---学生属性
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
} stu3;	//结构体变量创建方式3

//2、通过学生类型创建具体学生(共有3种方式)

//2.1、struct student s1; // s1就是变量名
//2.2、struct student s2 = {...}; // 创建变量的同时赋初值
//2.3、在定义结构体时顺便创建结构体变量

int main()
{
	//【结构体变量创建方式1】2.1、struct student s1;
	struct student stu1; //创建结构体时,struct关键字可以省略
	//给stu1属性赋值,通过“.”访问结构体变量中的属性
	stu1.name = "张三";
	stu1.age = 18;
	stu1.score = 100;
	//方式1打印输出
	cout << "姓名:" << stu1.name << " 年龄:" << stu1.age << " 分数:" << stu1.score << endl;

	//【结构体变量创建方式2】2.2、struct student s2 = {...};
	struct student stu2 = {"李四", 19, 60};
	//方式2打印输出
	cout << "姓名:" << stu2.name << " 年龄:" << stu2.age << " 分数:" << stu2.score << endl;

	//【结构体变量创建方式3】在定义结构体时顺便创建结构体变量,不建议使用
	stu3.name = "王五";
	stu3.age = 18;
	stu3.score = 80;
	//方式3打印输出
	cout << "姓名:" << stu3.name << " 年龄:" << stu3.age << " 分数:" << stu3.score << endl;

	system("pause");
	return 0;
}
  • 总结1:定义结构体时的关键字是struct,不可省略。
  • 总结2:创建结构体变量时,关键字struct可以省略。
  • 总结3:结构体变量利用操作符 ''.'' 访问成员。

8.3 结构体数组

作用:自定义的结构体放入到数组方便维护

语法:struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }

示例

 

#include <iostream>
#include <string>
using namespace std;

//结构体数组

//1、定义结构体
struct student
{
	//成员列表
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
};

int main()
{
	//2、创建结构体数组
	struct student stuArray[3] =
	{
		{"张三", 18, 88},
		{"李四", 28, 99},
		{"王五", 38, 66}
	};

	//3、给结构体数组中的元素赋值
	stuArray[2].name = "赵六";
	stuArray[2].age = 66;
	stuArray[2].score = 99;

	//4、遍历结构体数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << stuArray[i].name
			 << "\t年龄:" << stuArray[i].age
			 << "\t分数:" << stuArray[i].score << endl;
	}

	system("pause");
	return 0;
}

8.4 结构体指针

作用:通过指针访问结构体中的成员// 利用结构体指针操作结构体成员

  • 利用操作符 ->可以通过结构体指针访问结构体属性

示例

 &s:取s的地址,返回s对应的数据类型的指针。

 

#include <iostream>
#include <string>
using namespace std;

//结构体指针

//1、定义学生结构体
struct student
{ //成员列表
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
};

int main()
{
	//2、创建学生结构体变量
	// struct student stu = {"张三", 25, 100}; //struct可以省略
	student stu = {"张三", 25, 99}; //struct可以省略

	//3、通过指针指向结构体变量
	// struct student *p = &stu; //struct可以省略
	student *p = &stu; //struct可以省略

	//结构体变量,可以直接通过.来访问
	cout << "姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;

	//4、通过指针访问结构体变量中的数据
	p->score = 66; //指针通过 -> 操作符可以访问成员

	//通过结构体指针访问结构体中的属性,需要利用“->”
	cout << "姓名:" << p->name << "\t年龄:" << p->age << "\t分数:" << p->score << endl;

	system("pause");
	return 0;
}
  • 总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员。

8.5 结构体嵌套结构体

作用: 结构体中的成员可以是另一个结构体

例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体。

示例

#include <iostream>
#include <string>
using namespace std;

// 结构体嵌套结构体

//定义学生结构体
struct student
{
	//成员列表
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
};

//定义教师结构体
struct teacher
{
	//成员列表
	int id;				//教师编号
	string name;		//教师姓名
	int age;			//教师年龄
	struct student stu; //教师辅导的学生 子结构体
};

int main()
{
	//创建教师结构体变量
	struct teacher t1;
	t1.id = 333;
	t1.name = "老王";
	t1.age = 50;

	t1.stu.name = "张三";
	t1.stu.age = 18;
	t1.stu.score = 99;

	cout << "教师编号:" << t1.id
		 << "\t教师姓名:" << t1.name
		 << "\t教师年龄:" << t1.age
		 << "\t教师辅导的学生姓名:" << t1.stu.name
		 << endl;

	cout << "学生姓名:" << t1.stu.name
		 << "\t学生年龄:" << t1.stu.age
		 << "\t学生考试分数:" << t1.stu.score
		 << endl;

	system("pause");
	return 0;
}

总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题。

8.6 结构体做函数参数

作用:将结构体作为参数向函数中传递。

传递方式有2种:

  1. 值传递

  2. 地址传递

示例

#include <iostream>
#include <string>
using namespace std;

//定义学生结构体
struct student
{
	//成员列表
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
};

//打印学生信息函数
//1、值传递
void printStudent1(struct student stu) //(student stu)
{
	stu.age = 28; //修改属性
	cout << "1子函数中\t姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;
}

//2、地址传递
void printStudent2(struct student *stu) //用指针*stu接收地址
{
	stu->age = 28;
	cout << "2子函数中\t姓名:" << stu->name << "\t年龄:" << stu->age << "\t分数:" << stu->score << endl;
}

int main()
{
	//结构体作函数参数
	//将学生传入到一个参数中,打印学生身上的所有信息

	//创建结构体变量
	student stu = {"张三", 18, 100};
	stu.name = "李四";
	stu.age = 20;
	stu.score = 85;

	//1、值传递
	printStudent1(stu);
	cout << "1主函数中\t姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;

	cout << endl;

	//2、地址传递
	printStudent2(&stu);
	cout << "2主函数中\t姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;

	system("pause");
	return 0;
}

总结:如果不想修改主函数中的数据,用值传递,反之用地址传递。

8.7 结构体中const使用场景

作用:用const来防止误操作

示例

#include <iostream>
#include <string>
using namespace std;

//学生结构体定义
struct student
{
	//成员列表
	string name; //姓名
	int age;	 //年龄
	int score;	 //分数
};

/*
 * 值传递
 * stu.age = 150;//mian中的stu变量不会改变
 * 会将实参中的数据拷贝一份,放在形参s上
 * 无论形参如何改变,都不会影响实参
 * 1、实参有很多属性,每个属性都拷贝一份,拷贝的数据量很大
 * 2、假设一个学校有成千上万个人,每个人都调用printStudent函数,拷贝成千上万份数据,
 *    这样数据量就会非常大,占用内存空间大
 */
void printStudent1(student stu) // (struct student stu) 省略struct
{
	stu.age = 150; //mian中的stu变量不会改变
	cout << "姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;
}

// void printStudent3(const student stu) // (struct student stu) 省略struct
// {
// 	stu.age = 150; //mian中的stu变量不会改变
// 	cout << "姓名:" << stu.name << "\t年龄:" << stu.age << "\t分数:" << stu.score << endl;
// }

//将函数中的形参改为指针,可以减少内存空间的使用,而且不会复制新的副本出来(值传递会复制整个结构体元素)
//const使用场景
void printStudent2(const student *stu) //加const防止函数体中的误操作 指针*stu节省空间,一个指针占4个字节内存
{
	//stu->age = 100; //操作失败,因为加了const修饰,常量指针无法修改指针指向的值,只能读不能写。防止age的值会被修改
	//加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作(加“const”防止误操作)
	cout << "姓名:" << stu->name << "\t年龄:" << stu->age << "\t分数:" << stu->score << endl;
}

int main()
{
	//创建结构体变量
	student stu = {"张三", 18, 100};

	printStudent1(stu); //值传递

	//通过函数打印结构体变量信息
	printStudent2(&stu); //传入地址,在函数中指针接收地址

	cout << "main()中 张三的年龄为:" << stu.age << endl;

	system("pause");
	return 0;
}

8.8 结构体案例

8.8.1 案例1

案例描述:

学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:

  • 设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员;
  • 学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值;
  • 最终打印出老师数据以及老师所带的学生数据。

#include <iostream>
#include <string>
#include <ctime>
using namespace std;

//学生结构体
struct Student
{
    string sName; //姓名
    int score;    //分数
};

//老师结构体
struct Teacher
{
    string tName;             //姓名
    struct Student sArray[5]; //学生数组
};

//创建数据——给老师和学生赋值的函数
void allocateSpace(struct Teacher tArray[], int len) //struct可以省略
{
    string tName = "老师"; // Teacher_
    string sName = "学生";
    string nameSeed = "ABCDE";
    //给老师进行赋值
    for (int i = 0; i < len; i++)
    {
        tArray[i].tName = tName + nameSeed[i]; //老师姓名
        //通过循环给每名老师所带的学生进行赋值
        for (int j = 0; j < 5; j++)
        {
            tArray[i].sArray[j].sName = sName + nameSeed[j];
            tArray[i].sArray[j].score = rand() % 61 + 40; // 0~60 40~100
            // rand() % 60:0~59
        }
    }
}

//打印数据——打印所有信息
void printTeachers(struct Teacher tArray[], int len) //struct可以省略
{
    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)); //随机数种子 头文件 #include <ctime>

    //1、创建3名老师的数组
    struct Teacher tArray[3]; //老师数组 struct可以省略

    //2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
    cout << "string类型所占内存空间为:" << sizeof(string) << endl; //string类型所占内存空间为:32
    cout << "int类型所占内存空间为:" << sizeof(int) << endl; //int类型所占内存空间为:4
    cout << "sizeof(tArray):" << sizeof(tArray) << endl;            //sizeof(tArray):696
    cout << "sizeof(Teacher):" << sizeof(Teacher) << endl;          //sizeof(Teacher):232
    cout << "sizeof(Student):" << sizeof(Student) << endl;          //sizeof(Student):40
    cout << "sizeof(tArray[0]):" << sizeof(tArray[0]) << endl;      //sizeof(tArray[0]):232
    int len1 = sizeof(tArray) / sizeof(Teacher);                     //计算数组长度
    cout << "len1:" << len1 << endl;                                //len1:3
    int len2 = sizeof(tArray) / sizeof(tArray[0]);                   //计算数组长度
    cout << "len2:" << len2 << endl;                                //len2:3
    allocateSpace(tArray, len2);                                     //创建数据

    //3、打印所有老师及所带的学生信息
    printTeachers(tArray, len2); //打印数据

    system("pause");
    return 0;
}

8.8.2 案例2

案例描述:

设计一个英雄的结构体,包括成员姓名、年龄、性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

五名英雄信息如下:

{"刘备", 23, "男"},
{"关羽", 22, "男"},
{"张飞", 20, "男"},
{"赵云", 21, "男"},
{"貂蝉", 19, "女"},

#include <iostream>
#include <string>
using namespace std;

//1、设计英雄结构体
//英雄结构体
struct hero
{
    string name; //姓名
    int age;     //年龄
    string sex;  //性别
};

//冒泡排序——实现年龄升序排列
void bubbleSort(struct hero arr[], int len) //struct可省
{
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - 1 - i; j++)
        {
            //如果j下标的元素年龄大于j+1下标的元素的年龄,交换两个元素
            if (arr[j].age > arr[j + 1].age)
            {
                struct hero temp = arr[j]; //临时数据
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

//打印数组——打印排序后数组中的信息
void printHeros(struct hero arr[], int len) //struct可省
{
    for (int i = 0; i < len; i++)
    {
        cout << "姓名:" << arr[i].name << "\t性别:" << arr[i].sex << "\t年龄:" << arr[i].age << endl;
    }
}

//1、设计英雄结构体
//2、创建数组存放5名英雄
//3、对数组进行排序,按照年龄进行升序排序
//4、将排序后的结果打印输出
int main()
{
    //2、创建数组存放5名英雄
    struct hero heroArray[5] =
        {
            {"刘备", 23, "男"},
            {"关羽", 22, "男"},
            {"张飞", 20, "男"},
            {"赵云", 21, "男"},
            {"貂蝉", 19, "女"}};

    cout << "string类型所占内存空间为:" << sizeof(string) << endl;   //string类型所占内存空间为:32
    cout << "int类型所占内存空间为:" << sizeof(int) << endl;         //int类型所占内存空间为:4
    cout << "sizeof(heroArray):" << sizeof(heroArray) << endl;       //sizeof(heroArray):360
    cout << "sizeof(heroArray[0]):" << sizeof(heroArray[0]) << endl; //sizeof(heroArray[0]):72
    cout << "sizeof(hero):" << sizeof(hero) << endl;                 //sizeof(hero):72

    int len1 = sizeof(heroArray) / sizeof(heroArray[0]); //整体所占空间大小/单个元素所占空间大小
    cout << "len1:" << len1 << endl;                    //len1:5
    int len2 = sizeof(heroArray) / sizeof(hero);         //获取数组元素个数
    cout << "len2:" << len2 << endl;                    //len1:5

    cout << "排序前,数组打印:" << endl;
    for (int i = 0; i < len1; i++)
    {
        cout << "姓名:" << heroArray[i].name << "\t性别:" << heroArray[i].sex << "\t年龄:" << heroArray[i].age << endl;
    }

    //3、对数组进行排序,按照年龄进行升序排序
    bubbleSort(heroArray, len1); //排序

    cout << "排序后,数组打印:" << endl;

    //4、将排序后的结果打印输出
    printHeros(heroArray, len1); //打印

    system("pause");
    return 0;
}

此案例锻炼的3点:

  1. 结构体数组的写法
  2. 冒泡排序 // 使用“冒泡排序”对结构体数组进行排序
  3. 结构体传入函数的写法、操作结构体的写法
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值