目录
一、概念、定义和使用
- 结构体——用户自定义的数据类型,允许用户存储不同的数据类型
struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的三种方式:
- struct 结构体名 变量名
- struct 结构体名 变量名={ 成员1值,成员2值…}
- 定义结构体时顺便创建变量
#include<iostream>
#include<string>
using namespace std;
struct student
{
string name;
int age;
int score;
};
int main()
{
//第一种
struct student s1;
s1.name="张三";
s1.age=18;
s1.score=100;
cout<<"姓名:"<<s1.name<<'\t'<<"年龄:"<<s1.age<<'\t'<<"成绩:"<<s1.score<<endl;
//第二种
struct student s2={"李四",17,98};
cout<<"姓名:"<<s2.name<<'\t'<<"年龄:"<<s2.age<<'\t'<<"成绩:"<<s2.score<<endl;
return 0;
}
struct student
{
string name;
int age;
int score;
}s3; //第三种
二、结构体数组
(将自定义的结构体放入到数组中方便维护)
struct 结构体名 数组名[ 元素个数 ] = { { },{ },……{ } }
#include<string>
using namespace std;
//结构体定义
struct student
{
string name;
int age;
int score;
};
int main()
{
//创建结构体数组
struct student stuArray[3]=
{
{"张三",18,100},
{"李四",17,98},
{"王五",15,60}
};
//给结构体数组中元素赋值
stuArray[0].name="果子";
//遍历结构体数组
for(int i=0;i<3;i++)
{
cout<<"姓名:"<<stuArray[i].name<<"年龄:"<<stuArray[i].age<<"成绩:"<<stuArray[i].score<<endl;
}
return 0;
}
三、结构体指针
(通过指针访问结构体中的成员)
- 利用操作符->可以通过结构体指针访问结构体属性
#include<iostream>
#include<string>
using namespace std;
//结构体定义
struct student
{
string name;
int age;
int score;
};
int main()
{
//创建学生结构体变量
struct student s={"张三",18,100}; //struct可省
//通过指针指向结构体
struct student *p = &s; //struct可省
//通过指针访问结构体变量中的数据
cout<<"姓名:"<<p->name<<endl;
return 0;
}
四、结构体嵌套结构体
(结构体中的成员可以是另一个结构体—如:老师:结构体;老师的学生:结构体)
#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 s1;//嵌套
};
int main()
{
struct teacher t;
t.id=111;
t.name="李四";
t.age=30;
t.s1.name="张六";
t.s1.age=18;
t.s1.score=100;
cout<<"学生姓名:"<<t.s1.name<<endl;
return 0;
}
五、结构体做函数参数
(将结构体作为参数向函数中传递)
- 值传递
- 地址传递
#include<iostream>
#include<string>
using namespace std;
//结构体定义
struct student
{
string name;
int age;
int score;
};
//打印学生信息函数
//1.值传递
void printstu1(struct student s)
{
s.age=100;
cout<<"在子函数1中打印 姓名:"<<s.name<<"年龄:"<<s.age<<"分数:"<<s.score<<endl;
}
//2.地址传递
void printstu2(struct student * p)//用指针接收地址
{
p->age=200;
cout<<"在子函数2中打印 姓名:"<<p->name<<"年龄:"<<p->age<<"分数:"<<p->score<<endl;
}
int main()
{
//结构体做函数参数
//将学生传入到一个参数中,打印学生身上的所有信息
//创建结构体变量
struct student s1;
s1.name="张三";
s1.age=18;
s1.score=90;
printstu1(s1);
printstu2(&s1);
cout<<"main函数中打印 姓名:"<<s1.name<<"年龄:"<<s1.age<<"分数:"<<s1.score<<endl;
return 0;
}
六、结构体中const使用场景
(用const来防止误操作)
#include<iostream>
#include<string>
using namespace std;
//结构体定义
struct student
{
string name;
int age;
int score;
};
//将函数中的形参改为指针(值传递—>地址传递),可以减少内存空间,而且不会复制一个新的副本出来
//但地址传递容易改变实参的值,为了防止误操作+const,一旦有修改的操作会报错
void printstu(const struct student *s)
{
cout<<"姓名:"<<s->name<<"年龄:"<<s->age<<"分数:"<<s->score<<endl;
}
int main()
{
//创建结构体变量
struct student s1;
s1.name="张三";
s1.age=18;
s1.score=90;
//通过函数打印结构体变量信息
printstu(&s1);
cout<<"姓名:"<<s1.name<<"年龄:"<<s1.age<<"分数:"<<s1.score<<endl;
return 0;
}
七、结构体案例
案例1
#include<iostream>
#include<string>
#include<ctime>
using namespace std;
/*案例1:
学校在做毕设项目,每名老师带领5个学生,共3名老师
设计老师和学生的结构体
老师结构体:老师姓名、存放5名学生的数组作为成员
学生结构体:学生姓名、考试分数
创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
最终打印除老师数据及老师所带的学生数据
*/
struct student
{
string name;
int score;
};
struct teacher
{
string name;
struct student stu[5];
};
//给老师和学生赋值的函数
void allocateSpace(struct teacher tea[],int len)
{
string nameSeed = "ABCDE";
for(int i=0;i<len;i++)
{
tea[i].name ="teacher_";
tea[i].name += nameSeed[i];//i的位置
//通过循环给每名老师的学生赋值
for(int j=0;j<5;j++)
{
tea[i].stu[j].name ="student_";
tea[i].stu[j].name += nameSeed[j];
int random = rand()%61+40;//(0~60)+40=(40~100)之间的随机数
tea[i].stu[j].score = random;
}
}
}
//打印所有信息
void printInfo(struct teacher tea[],int len)
{
for(int i=0;i<len;i++)
{
cout<<"老师姓名:"<<tea[i].name<<endl;
for(int j=0;j<5;j++)
{
cout<<"\t学生姓名:"<<tea[i].stu[j].name<<" 学生成绩:"<<tea[i].stu[j].score<<endl;
}
}
}
int main()
{
//随机数种子
srand((unsigned int)time(NULL));
//创建3名老师的数组
struct teacher tea[3];
//通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
allocateSpace(tea,3);//传数组名
//打印
printInfo(tea,3);
return 0;
}
/*结果:
老师姓名: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
*/
案例2
#include<iostream>
#include<string>
using namespace std;
/*案例2:
设计一个英雄的结构体:成员姓名、年龄、性别
创建结构体数组,数组中存放5名英雄
通过冒泡排序的算法,将数组中的影响按照年龄进行升序排序,最终打印排序后的结果
*/
struct hero
{
string name;
int age;
string sex;
};
//冒泡升序排序
void Bubble(struct hero h[],int len)
{
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-i-1;j++)
{
if(h[j].age>h[j+1].age)
{
struct hero temp=h[j];
h[j]=h[j+1];
h[j+1]=temp;
}
}
}
}
//打印
void printHero(struct hero h[],int len)
{
for(int i=0;i<len;i++)
{
cout<<"英雄姓名:"<<h[i].name<<" 英雄年龄:"<<h[i].age<<" 英雄性别:"<<h[i].sex<<endl;
}
}
int main()
{
struct hero heroArray[5]=
{
{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"男"},
{"貂蝉",19,"女"}
};
int len=sizeof(heroArray)/sizeof(heroArray[0]);
Bubble(heroArray,len);
printHero(heroArray,len);
return 0;
}
/*结果:
英雄姓名:貂蝉 英雄年龄:19 英雄性别:女
英雄姓名:张飞 英雄年龄:20 英雄性别:男
英雄姓名:赵云 英雄年龄:21 英雄性别:男
英雄姓名:关羽 英雄年龄:22 英雄性别:男
英雄姓名:刘备 英雄年龄:23 英雄性别:男
*/