结构体概念:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
(一)结构体定义和使用
(二)结构体数组和指针
(三)结构体嵌套结构体
(四)结构体做函数参数
(五)结构体中const使用场景
(一)结构体定义和使用
struct 结构体名称(结构体成员列表)
定义结构体:
struct Student
{
string name;
int age;
int score;
};
通过结构体创建变量的方式有三种:
(1) struct 结构体名 变量名
(2) struct 结构体名 变量名 = {成员1值,成员2值,…}
(3) 定义结构体时顺便创建变量
通过结构体创建变量:
(1) struct Student s1;
给s1的属性赋值:
s1.mame = "张三"; 使用的话需要新加 #include <string> 的头文件
s1.age = 18;
s1.score = 100;
(2) struct Stduent s2 = {"张三",18,100};
(3)struct Student
{
string name;
int age;
int score;
}s3;
(二)结构体数组和指针
结构体数组
#include <iostream>
using namespace std;
#include <string>
struct Student
{
string name;
int age;
int score;
};
int main()
{
struct Student Stu[3] =
{
{"张三",18,100},{"李四",17,95},{"王五",19,99}
};
for (int i = 0; i < 3; i++)
{
cout << "学生姓名为:" << Stu[i].name << " 学生年龄为:"
<< Stu[i].age << " 学生分数为:" << Stu[i].score << endl;
}
cout << endl;
system("pause");
return 0;
}
输出:
学生姓名为:张三 学生年龄为:18 学生分数为:100
学生姓名为:李四 学生年龄为:17 学生分数为:95
学生姓名为:王五 学生年龄为:19 学生分数为:99
请按任意键继续. . .
结构体指针
使用 p->age 输出
//写成struct Student也可以,struct可以省略
Student s = { "张三",18,100 };
//同样,struct也是可以省略的
Student* p = &s;
cout << "学生姓名为:" << p->name << " 学生年龄为:"
<< p->age << " 学生分数为:" << p->score << endl;
(三)结构体嵌套结构体
#include <iostream>
using namespace std;
#include <string>
//定义学生结构体
struct stu
{
string name;
int score;
};
//定义老师结构体
struct teacher
{
string name;
int id;
struct stu s;
};
int main()
{
teacher t;
t.name = "王老师";
t.id = 12345678;
t.s.name = "张三";
t.s.score = 100;
cout << "老师的名字是:" << t.name << "\n"
<< "老师的ID是:" << t.id <<"\n"
<< "老师所带学生的名字是:" << t.s.name << "\n"
<< "老师所带学生的分数是:" << t.s.score << endl;
system("pause");
return 0;
}
输出:
(四)结构体做函数参数
#include <iostream>
using namespace std;
#include <string>
struct student
{
string name;
int age;
};
//打印学生信息函数
//1.值传递
void printS1(struct student s)
{
cout << " 值传递,学生姓名为:" << s.name << " 年龄为:" << s.age << endl;
}
//2.地址传递
void printS2(struct student * p)
{
cout << "地址传递,学生姓名为:" << p->name << " 年龄为:" << p->age << endl;
}
int main()
{
struct student s;
s.name = "张三";
s.age = 20;
printS1(s);
printS2(&s);
system("pause");
return 0;
}
输出:
值传递,学生姓名为:张三 年龄为:20
地址传递,学生姓名为:张三 年龄为:20
请按任意键继续. . .
注意点:值函数与地址函数的区别
(1)在值传递函数中,如果改动年龄,设置为50岁,那么值函数传递出的年龄就是50岁,但原函数不变,仍为20岁。
(2)在地址传递函数中,如果改动年龄,设置为60岁,那么值函数传递出的年龄是60岁,且原函数也变化为60岁。
如果不想修改主函数中的数据,用值传递;反之,地址传递。
(五)结构体中const使用场景
const作用:防止误操作
将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来。
void printS1(student * p)
{
p->age = 50;
cout << "地址传递,学生姓名为:" << p->name << " 年龄为:" << p->age << endl;
}
int main()
{
struct student s = { "张三" ,20 };
printS1(&s);
cout << "main函数中,学生姓名为:" << s.name << " 年龄为:" << s.age << endl;
system("pause");
return 0;
}
此时输出均为:50岁。
但如果在函数定义处加上const:
void printS1(const student * p)
{
p->age = 50;
cout << "地址传递,学生姓名为:" << p->name << " 年龄为:" << p->age << endl;
}
再次运行会出错,因为加上const之后变成了只读模式,写入p->age = 50;是错误的。
【案例1】
做项目,共2名老师,每个老师带3名学生。要求:
设计学生和老师的结构体,在老师的结构体中,有老师姓名和一个存放3名学生的数组,学生的成员有姓名和分数。创建数组存放2名老师,通过函数给每个老师和学生赋值,最终打印出老师数据和老师所带学生数据。
#include <iostream>
using namespace std;
#include <string>
#include <ctime>
struct stu
{
string name;
int score;
};
struct teach
{
string name;
struct stu s[3];
};
void allocate(struct teach t[],int len)
{
string nameSeed = "ABCDEF";
//给老师赋值
for (int i = 0; i < len; i++)
{
t[i].name = "Teacher_";
t[i].name += nameSeed[i];
for (int j = 0; j < 3; j++)
{
t[i].s[j].name = "Student_";
t[i].s[j].name += nameSeed[j];
int a = rand() % 61 + 40;//rand() % 61 表示:随机输出0到60。
t[i].s[j].score = a;
}
}
}
void printinf(struct teach t[],int len)
{
for (int i = 0; i < len; i++)
{
cout << "老师的姓名:" << t[i].name << endl;
for (int j = 0; j < 3; j++)
{
cout << "\t学生的姓名:" << t[i].s[j].name << " 学生的分数:" << t[i].s[j].score << endl;
}
cout << "\n" << endl;
}
}
int main()
{
srand((unsigned int)time(NULL));
struct teach t[2];
int len = sizeof(t) / sizeof(t[0]);
allocate(t, len);
printinf(t, len);
system("pause");
return 0;
}
输出:
老师的姓名:Teacher_A
学生的姓名:Student_A 学生的分数:74
学生的姓名:Student_B 学生的分数:94
学生的姓名:Student_C 学生的分数:42
老师的姓名:Teacher_B
学生的姓名:Student_A 学生的分数:79
学生的姓名:Student_B 学生的分数:66
学生的姓名:Student_C 学生的分数:66
请按任意键继续. . .
【案例2】
设计一个英雄结构体,包括成员姓名、年龄,创建结构体数组,数组中存放5名英雄,通过冒泡排序算法,将数组中英雄按照年龄升序排序,打印排序结果。
#include <iostream>
using namespace std;
#include <string>
#include <ctime>
struct hero
{
string name;
int age;
};
void allocate(struct hero h[], int len)
{
string nameSeed = "ABCDEF";
for (int i = 0; i < len; i++)
{
h[i].name = "HERO_";
h[i].name += nameSeed[i];
int a = rand() % 101;
h[i].age = a;
}
}
void bubble(struct hero h[], int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (h[j].age > h[j + 1].age)
{
int temp = h[j].age;
h[j].age = h[j + 1].age;
h[j + 1].age = temp;
}
}
}
cout << "冒泡排序后序列输出:\n";
for (int i = 0; i < len; i++)
{
cout << "名字是:\t" << h[i].name << "\t年龄是:" << h[i].age << "\n" << endl;
}
cout << endl;
}
int main()
{
srand((unsigned int)time(NULL));
struct hero h[5];
int len = sizeof(h) / sizeof(h[0]);
allocate(h,len);
for (int i = 0; i < len; i++)
{
cout << "名字是:\t" << h[i].name << "\t年龄是:" << h[i].age << "\n" << endl;
}
bubble(h, len);
system("pause");
return 0;
}
输出:
名字是: HERO_A 年龄是:21
名字是: HERO_B 年龄是:3
名字是: HERO_C 年龄是:77
名字是: HERO_D 年龄是:4
名字是: HERO_E 年龄是:33
冒泡排序后序列输出:
名字是: HERO_A 年龄是:3
名字是: HERO_B 年龄是:4
名字是: HERO_C 年龄是:21
名字是: HERO_D 年龄是:33
名字是: HERO_E 年龄是:77
请按任意键继续. . .