C++ 结构体—struct
Date:2021.9.30
Author:lqy
文章目录
一、结构体简介:
-
结构体属于C++中一种自定义数据类型,struct为基本数据类型的集合
-
结构体定义:
struct 结构体名 { 成员列表; };
-
结构体创建:
1. struct 结构体名 结构体对象; 2. struct 结构体名 结构体对象 = {成员列表初始化}; 3. 创建结构体同时定义结构体对象
-
代码示例:
struct Student { /*成员列表*/ string name; int age; int score; }s3; void test01() { /*1. 单独创建结构体对象*/ struct Student s1; s1.name = "liiqyan"; s1.age = 20; s1.score = 300; /*2. 创建对象时进行对象属性初始化*/ struct Student s2 = { "liqiyan",10,300 }; /*3. 在定义结构体时创建结构体变量*/ s3.name = "liqiyan"; s3.age = 10; s3.score = 300; }
二、结构体数组:
-
结构体数组简介:
结构体数组中每一个元素均为结构体,可以将结构体视作与基本数据类型等同的自定义数据类型
-
代码示例:
struct Student { /*结构体定义*/ string name; int age; int score; }; void test01() { /*数据类型为自定义结构体数据类型*/ struct Student arr[] = { /*结构体创建时初始化*/ {"liqiyan",10,100}, {"linxuan",20,90}, {"liujingke",30,60} }; for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { /*利用sizeof方法获取数组中元素个数,sizeof(arr)/sizeof(arr[0])*/ /*"\t"用于输出对齐*/ cout << "name:" << arr[i].name << "\t"<<"age:" << arr[i].age <<"\t" <<"score:" << arr[i].score << endl; } }
三、结构体指针
-
结构体指针简介:
结构体指针是指针和结构体的结合,利用指针接受结构体变量
-
结构体指针使用:
结构体指针访问成员对象与结构体对象".“的方式不同,结构体指针借助于**”->"**访问成员变量
-
代码示例:
/*结构体指针借助于"->"访问结构体中的成员变量*/ struct Student { string name; int age; int score; }; void test01() { /*结构体变量定义以及初始化*/ struct Student s = { "liqiyan",10,300 }; /*创建结构体指针,利用指针p接受结构体对象的地址(&取址符)*/ Student* p = &s; cout << "name:" << p->name << "\t" << "age:" << p->age << "\t" << "score:" << p->score << endl; }
四、结构体嵌套结构体
-
结构体嵌套:
结构体中嵌套另外的结构体,作为结构体的成员变量
-
代码示例:
struct Student { string name; int num; double score; }; struct Teacher { int id; string name; int age; /*自定义数据类型结构体定义结构体对象作为新结构体的成员变量*/ struct Student s; }; void test01() { struct Student s = { "liqiyan",201901,100 }; /*结构体嵌套结构体初始化*/ struct Teacher t = { 1,"zhangyong",40,s }; }
五、结构体作为函数参数:
-
参数传递两种方式:
- 值传递:形参不会修饰实参(形参的改变不影响实参的取值)
- 地址传递:形参修饰实参(形参的改变会影响实参的取值)
-
代码示例:
struct Student { string name; int age; int score; }; void printStudent(struct Student s) { /*值传递方式->形参不会修饰实参,结构体对象使用"."的方式实现成员属性的调用*/ cout << "name:" << s.name << "age:" << s.age << "score:" << s.score << endl; } void showStudent(struct Student *p) { /*地址传递方式->形参修饰实参,结构体指针使用"->"的方式实现成员属性的调用*/ cout << "name:" << p->name << "age:" << p->age << "score:" << p->score << endl; }
六、结构体中const的使用场景:
-
const使用时机:
-
在程序实际开发中,函数参数一般情况下均采用地址传递的方式进行传递,原因在于值传递方式原在元数据上的基础上拷贝出一份新数据,会占用更多的内存,因此实际开发中一般采用地址传递
-
地址传递由于形参会修饰实参,因此可能会存在程序员误操作将原结构体对象中的属性修改,因此需要加入限定符限定为只读状态,不支持外界修改
-
-
代码示例:
struct Student { string name; int age; int score; }; /*地址传递+const限定符修饰*/ void showStudent(const struct Student *s) { // s->name = "linxuan"; //代码错误->const表示左值仅可读,不可写 cout << "name:" << s->name << "age:" << s->age << "score:" << s->score << endl; }
七、结构体案例:
-
毕业设计案例:
共有三位老师,每位老师带领5位学生做毕业设计项目,结合结构体数组,结构体嵌套等等技术实现功能需求
struct Student { string name; int score; }; struct Teacher { string name; struct Student arr[5]; //结构体嵌套结构体数组 }; void allocate(struct Teacher tArray[], int len) { /*tArray:教师结构体数组,本质上为数组,引用数据类型,形参会修饰实参 len:结构体数组长度*/ string nameSeed = "ABCDE"; for (int i = 0; i < len; i++) { /*Teacher结构体成员属性赋值*/ tArray[i].name = "Teacher_"; tArray[i].name += nameSeed[i]; for (int j = 0; j < 5; j++) { /*Student结构体成员属性赋值*/ tArray[i].arr[j].name = "Student_"; tArray[i].arr[j].name += nameSeed[i]; /*学生成绩赋值采用随机数产生的方式*/ int random = rand() % 61 + 40; // 40-100 tArray[i].arr[j].score = random; } } } void printInfo(struct Teacher tArray[],int len) { /*教师、学生基本情况显示*/ for (int i = 0; i < len; i++) { for (int j = 0; j < 5; j++) { cout << "Teacher-name:" << tArray[i].name << "\t" << "Student" << " " << j << "\t" << "name:" << tArray[i].arr[j].name << "\t" << "score:" << tArray[i].arr[j].score << endl; } cout << endl; } } void test01() { /*设置随机数种子,根据系统时间产生真正的随机数*/ srand((unsigned int)time(NULL)); struct teacher tarray[3]; /*利用sizeof方法获得数组长度->sizeof(tAyyay)/sizeof(tArray[0])*/ int len = sizeof(tarray) / sizeof(tarray[0]); allocate(tarray, len); printinfo(tarray, len); }
-
英雄案例:
结构体存储多位英雄,并结合冒泡排序按照年龄对英雄进行排序
struct Hero { string name; int age; string sex; }; void showHero(struct Hero arr[], int len) { /*传入结构体数组和数组长度实现英雄基本信息的输出*/ for (int i = 0; i < len; i++) { cout <<"name:"<< arr[i].name <<"\t"<<"age:"<< arr[i].age <<"\t"<<"sex:"<< arr[i].sex << endl; } } void bubbleSort(struct Hero arr[],int len) { /*冒泡排序*/ for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { /*在此处按照年龄进行冒泡排序*/ if (arr[j].age > arr[j + 1].age) { struct Hero temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
额外收获:C++随机数生成
/*
rand() % (a+1) + b ---->用于产生(b~a+b)之间的随机数
*/
srand((unsigned int)time(NULL)); //根据系统时间生成,避免生成相同随机数
int random = rand() % 61 + 40; //用于产生40-100之间的随机数
cout << random << endl;