关于P64~P71-练习-结构体
1、结构体的定义和使用
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
语法: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;
}s3;//2.3 定义结构体时顺便创建变量
//2、通过学生类型创建具体学生
int main()
{
//2.1 struct Student s1
//struct关键字可以省略
//struct Student s1;
Student s1;
//给s1属性赋值,通过.访问结构体变量中的属性
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << "姓名:" << s1.name << "年纪:" << s1.age << "成绩:" << s1.score << endl;
//2.2 struct Student s2 ={……}
struct Student s2 = { "李四", 19 , 80 };
cout << "姓名:" << s2.name << "年纪:" << s2.age << "成绩:" << s2.score << endl;
//2.3 定义结构体时顺便创建变量
s3.name = "王五";
s3.age = 20;
s3.score = 70;
cout << "姓名:" << s3.name << "年纪:" << s3.age << "成绩:" << s3.score << endl;
system("pause");
return 0;
}
问题:cout下面多了红色波浪线
解决方法:把前面的命名空间注释掉,如:
#include< iostream>
//using namespace std;
然后再改回去:
#include< iostream>
using namespace std;
奇奇怪怪的就好了,但是不晓得原因。。。
2、结构体数组
将自定义的结构体放入数组中方便维护。
语法:struct 结构体名 数组名[元素个数]={{},{},……{}}
#include<iostream>
#include<string>
using namespace std;
//结构体数组
//1、定义结构体
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//2、创建结构体数组
struct Student stuArray[3]=
{
{"张三",19,100},
{"李四",18,80},
{"王五",20,90}
};
//3、给结构体数组中的元素赋值
stuArray[2].name = "赵六";
stuArray[2].age = 30;
stuArray[2].score = 95;
//4、遍历结构体数组
for (int i = 0;i < 3;i++)
{
cout << "姓名:" << stuArray[i].name <<" "
<< "年龄:" << stuArray[i].age << " "
<< "成绩:" << stuArray[i].score << " " << endl;
}
system("pause");
return 0;
}
3、结构体指针
通过指针访问结构体中成员
利用操作符->
可以通过结构体指针访问结构体属性
#include<iostream>
#include<string>
using namespace std;
//结构体指针
//定义学生的结构体
struct Student
{
string name; //姓名
int age; //年龄
int score; //分数
};
int main()
{
//1、创建学生结构体变量
struct Student s = { "张三",18,100 };
//2、通过指针指向结构体变量
struct Student * p = &s;
//3、通过指针访问结构体变量中的数据
//利用操作符->可以通过结构体指针访问结构体属性
cout << "姓名:" << p->name << " "
<< "年龄:" << p->age << " "
<< "成绩:" << p->score << " " << endl;
system("pause");
return 0;
}
4、结构体嵌套结构体
例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体。
#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 t = { 1,"张老师",40,{"张三",18,100} };
/*struct teacher t;
t.id = 10000;
t.name = "老王";
t.age = 40;
t.stu.name = "小王";
t.stu.age = 19;
t.stu.score = 100;*/
cout << "老师姓名:" << t.name << endl
<< "老师id:" << t.id << endl
<< "老师年龄:" << t.age << endl
<< "老师辅导的学生姓名:" << t.stu.name << endl
<< "老师辅导的学生年龄:" << t.stu.age << endl
<< "老师辅导的学生成绩:" << t.stu.score << endl;
system("pause");
return 0;
}
5、结构体做函数参数
结构体作为参数向函数中传递,传递方式有两种:
1、值传递-形参变,实参不变
2、地址传递-形参变,实参变
#include<iostream>
#include<string>
using namespace std;
//结构体做函数的参数
//将学生传入到一个参数中,打印学生身上的所有信息
//定义学生的结构体
struct Student
{
string name; //姓名
int age; //年龄
int score; //分数
};
//打印学生信息函数
//1、值传递
void printStudent1(struct Student s)
{
s.age = 100;
cout << "printstudent1中打印结果:" << endl
<< "学生姓名:" << s.name << endl
<< "学生年龄:" << s.age << endl
<< "学生成绩:" << s.score << endl;
}
//2、地址传递
void printStudent2(struct Student *p)
{
p->age = 200;
cout << "printstudent2中打印结果:" << endl
<< "学生姓名:" << p->name << endl
<< "学生年龄:" << p->age << endl
<< "学生成绩:" << p->score << endl;
}
int main()
{
struct Student s;
s.name = "张三";
s.age = 18;
s.score = 100;
printStudent1(s);
cout << "main中打印结果:" << endl
<< "学生姓名:" << s.name << endl
<< "学生年龄:" << s.age << endl
<< "学生成绩:" << s.score << endl;
//struct student *p = &s;
printStudent2(&s);
cout << "main中打印结果:" << endl
<< "学生姓名:" << s.name << endl
<< "学生年龄:" << s.age << endl
<< "学生成绩:" << s.score << endl;
system("pause");
return 0;
}
问题:
使用了未定义类型“Student”
note: 参见“Student”的声明
“.age”的左边必须有类/结构/联合
解决方法:将定义的结构体放到定义的函数之前
6、结构体中const使用场景
作用:用const防止误操作。
#include<iostream>
#include<string>
using namespace std;
//结构体中const使用场景
//定义学生的结构体
struct Student
{
string name; //姓名
int age; //年龄
int score; //分数
};
//打印学生信息函数
//将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printStudent(const struct Student *s)
{
//s->age = 100;//加入const之后,一旦有修改操作就会报错,可以防止我们误操作
cout << "printstudent1中打印结果:" << endl
<< "学生姓名:" << s->name << endl
<< "学生年龄:" << s->age << endl
<< "学生成绩:" << s->score << endl;
}
int main()
{
struct Student s;
s.name = "张三";
s.age = 18;
s.score = 100;
//通过函数打印结构体变量信息
printStudent(&s);
cout << "main中打印结果:" << endl
<< "学生年龄:" << s.age << endl;
system("pause");
return 0;
}
7、结构体案例1-毕业设计
案例描述:学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:
1、设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员,学生成员有姓名,考试分数
2、创建数组存放3名老师
3、通过函数给每个老师及所带的学生赋值
4、最终打印出老师数据以及老师所带的学生数据
#include<iostream>
#include<string>
#include<ctime>
using namespace std;
//1、设计学生和老师的结构体
//其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员
//学生成员有姓名,考试分数
//定义学生结构体
struct student
{
//姓名
string sName;
//成绩
int score;
};
//定义老师结构体
struct teacher
{
//姓名
string tName;
//学生数组
struct student sArry[5];
};
//给老师和学生赋值函数
void allocateSpace(struct teacher tArry[],int len)
{
string nameSeed = "ABCDE";
//给老师赋值
for (int i = 0;i < len;i++)
{
tArry[i].tName = "Teacher_";
tArry[i].tName += nameSeed[i];
//通过循环给每名老师所带学生赋值
int len1 = sizeof(tArry[i].sArry) / sizeof(tArry[i].sArry[0]);
for (int j = 0;j < len1;j++)
{
tArry[i].sArry[j].sName = "Student_";
tArry[i].sArry[j].sName += nameSeed[j];
//需要加随机数种子
int random = rand() % 61 + 40;//0+40~60+40
tArry[i].sArry[j].score = random;
}
}
}
//打印出老师数据以及老师所带的学生数据函数
void printInfo(struct teacher tArry[], int len)
{
for (int i = 0;i < len;i++)
{
cout << "老师姓名:" << tArry[i].tName << endl;
cout << "该老师所带学生信息:" << endl;
int len1 = sizeof(tArry[i].sArry) / sizeof(tArry[i].sArry[0]);
for (int j = 0;j < len1;j++)
{
cout << "\t学生姓名:" << tArry[i].sArry[j].sName << " "
<< "学生成绩:" << tArry[i].sArry[j].score << endl;
}
}
}
int main()
{
//随机数种子
srand((unsigned int)time(NULL));//加#include<ctime>
//2、创建数组存放3名老师
struct teacher tArry[3] = {};
//3、通过函数给每个老师及所带的学生赋值
int len = sizeof(tArry) / sizeof(tArry[0]);
allocateSpace(tArry,len);
//4、最终打印出老师数据以及老师所带的学生数据
printInfo(tArry, len);
system("pause");
return 0;
}
注意:
1、\t的使用
2、随机数种子的使用
#include<ctime>
srand((unsigned int)time(NULL));
int random = rand() % 61 + 40;
3、命名的小窍门
string nameSeed = "ABCDE";
for (int i = 0;i < len;i++)
{
tArry[i].tName = "Teacher_";
tArry[i].tName += nameSeed[i];
}
8、结构体案例2-英雄排名
案例描述:
设计一个英雄的结构体,包括成员姓名、年龄、性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
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 arry[], int len)
{
for (int i = 0;i < len - 1;i++)
{
for (int j = 0;j < len - i - 1;j++)
{
if (arry[j].age > arry[j + 1].age)
{
struct hero temp = arry[j];
arry[j] = arry[j + 1];
arry[j + 1] = temp;
}
}
}
}
//最终打印排序后的结果函数
void printHero(struct hero arry[], int len)
{
for (int i = 0;i < len;i++)
{
cout << "姓名:" << arry[i].name
<< " 年龄:" << arry[i].age
<< " 性别:" << arry[i].sex << endl;
}
}
int main()
{
//2、创建结构体数组,数组中存放5名英雄
struct hero arry[5]=
{
{ "刘备",23,"男" },
{ "关羽",22,"男" },
{ "张飞",20,"男" },
{ "赵云",21,"男" },
{ "貂蝉",19,"女" }
};
int len = sizeof(arry) / sizeof(arry[0]);
//3、通过冒泡排序算法,将数组中的英雄按照年龄进行升序排序
cout << "排序前打印结果:" << endl;
for (int i = 0;i < len;i++)
{
cout << "姓名:" << arry[i].name
<< " 年龄:" << arry[i].age
<< " 性别:" << arry[i].sex << endl;
}
bubbleSort(arry, len);
//4、最终打印排序后的结果。
cout << "排序后打印结果:" << endl;
printHero(arry, len);
system("pause");
return 0;
}
注意:冒泡排序中定义的temp是英雄的结构体,交换的值也是英雄的结构体
(测试过程中未考虑到这点,将英雄的年龄换了。。。)