C++开发语言基础学习
8 结构体
8.1 结构体的定义与使用
-
定义结构体类型(创建模版) :
struct 结构体名 {结构体成员列表}
struct Student{ string name; int age; int score; }
-
创建结构体变量(根据模板创建实体)三种方式:
-
struct 结构体名 结构体变量名
+ 各属性分别初始化struct Student s1; s1.name = "张三"; s1.age = 18; si.score = 100;
-
struct 结构体名 结构体变量名 = {……}
struct Student s1 = {"张三" , 18 , 100};
-
定义结构体类型时直接创建结构体变量
+ 各属性分别初始化struct Student{ string name; int age; int score; }s1; s1.name = "张三"; s1.age = 18; si.score = 100;
注意:在C++中创建结构体变量时 struct 关键字可以省略,但是定义结构体类型时不能省略关键字
-
-
可以将结构体
struct 结构体名
看作是用户自己创建的一种数据类型
8.2 结构体数组
-
定义:元素是结构体的数组
-
语法:
struct 结构体名 数组名[元素个数] = { {} , {} , …… }
-
实例:
/************** 结构体数组定义 **************/ struct Student arr_student[3] = { {"张三",18,100} , {"李四",19,90} , {"王五",18,79} }; /************** 结构体数组赋值 **************/ arr_student[0].name = "赵六"; arr_student[1].score = 50; arr_student[2].age = 33; /************** 结构体数组遍历 **************/ for(int i=0;i<3;i++) { cout << "姓名: " << arr_student[i].name << "\t年龄: " << arr_student[i].age << "\t分数: " << arr_student[i].score << endl; } /**************** 输出结果 ****************/ // 姓名: 赵六 年龄: 18 分数: 100 // 姓名: 李四 年龄: 19 分数: 50 // 姓名: 王五 年龄: 33 分数: 79
8.3 结构体指针
-
定义结构体指针:
struct 结构体名* p = &结构体变量名
-
访问结构体成员:
p->成员名
-
修改结构体成员:
p->成员名 = 值
-
实例:
/****************** 创建结构体变量 ********************/ struct Student s1 = { "张三",19,100 }; /****************** 创建结构体指针 ********************/ struct Student* p = &s1; /***************** 通过指针修改结构体 ******************/ p->age = 20; /***************** 通过指针访问结构体 ******************/ cout << "姓名: " << p->name << "\t年龄: " << p->age << endl;
8.4 结构体嵌套
-
实例:
struct Student { // 定义学生结构体类型 string name; int age; int score; } struct Class_grade1 { // 定义班级结构体类型 int class_id; int student_num; struct Student stu; // 成员中包括学生结构体类型 }
8.5 结构体做函数参数
-
参数传递方法:值传递、地址传递
-
两种传参方法的区别:值传递只在函数内部修改,不会对实际结构体产生影响;地址传递会对实际结构体的成员值产生影响
-
实例:
/********************** 值传递 ************************/ void print_val_prop(struct Student s) { s.name = "王五"; cout << s.name << "\t" << s.age << "\t" << s.score << endl; } /********************** 地址传递 ***********************/ void print_add_prop(struct Student* p) { s->name = "王五"; cout << p->name << "\t" << p->age << "\t" << p->score << endl; } int main() { struct Student s1 = { "张三",19,95 }; print_val_prop(s1); // 传入结构体 print_add_prop(&s1); // 传入结构体地址 system("pause"); return 0; }
8.6 const修饰结构体
-
作用:避免在结构体地址传递时,函数内部对结构体内容进行的修改,也就是将传入的结构体当做“只读文件”
-
修饰方式:
function(const struct 结构体名* p)
-
实例:
void print_add_prop(const struct Student* p) { s->name = "王五"; cout << p->name << "\t" << p->age << "\t" << p->score << endl; }
-
结构体综合案例1:毕业设计管理
三名老师,各带5名学生,学生包括名字和成绩,教师包括名字和学生,使用函数对所有信息赋值,最后打印所有信息
#include <iostream> #include <string> using namespace std; struct Student { string name; int score; }; struct Teacher { string name; struct Student std_arr[5]; }; void Teacher_Regist(Teacher* p,int tch_num) { for (int i = 0; i < tch_num; i++) { printf("请输入第%d个教师的姓名:", i+1); cin >> (p + i)->name; for (int j = 0; j < 5; j++) { printf("请输入本教师的第%d个学生姓名:", j + 1); cin >> (p + i)->std_arr[j].name; printf("请输入本教师的第%d个学生成绩:", j + 1); cin >> (p + i)->std_arr[j].score; } cout << "-----------------------------------------------" << endl; } } int main() { struct Teacher tch[3]; int tch_num = sizeof(tch) / sizeof(tch[0]); Teacher_Regist(tch, tch_num); for (int i = 0; i < tch_num; i++) { printf("教师%d:%s\n", i + 1, tch[i].name.c_str()); for (int j = 0; j < 5; j++) { cout << "\t\t学生" << j+1 << ":" << tch[i].std_arr[j].name << "\t" << tch[i].std_arr[j].score << "分" << endl; } } system("pause"); return 0; } /******************** 输出结果 **********************/ 教师1:焦施懿 学生1:薛晟医 98分 学生2:薛晟贰 85分 学生3:薛晟叁 95分 学生4:薛晟思 68分 学生5:薛晟伍 77分 教师2:焦施尔 学生1:秦念医 84分 学生2:秦念贰 71分 学生3:秦念叁 99分 学生4:秦念思 88分 学生5:秦念伍 89分 教师3:焦施散 学生1:程韧医 86分 学生2:程韧贰 96分 学生3:程韧叁 94分 学生4:程韧思 86分 学生5:程韧伍 31分
注意:第38行
printf("教师%d:%s\n", i + 1, tch[i].name.c_str())
中为什么要加.c_str()
?问题出现:在最初使用的是
printf("教师%d:%s\n", i + 1, tch[i].name)
,也就是C语言中打印字符串的方式,但是发现打印出的汉字是乱码,查找资料后得知是C和C++字符串风格不同导致的C++中使用 printf() 打印字符串的问题
C++中的
printf
函数需要一个C风格字符串(即以'\0'
结尾的字符数组)。而tch[i].name
的类型是std::string
,不是char[]
,直接使用%s
输出会出现问题,因为std::string
不能直接传递给%s
,它不是C风格字符串。 解决办法:
使用
.c_str()
将std::string
转换为C风格字符串:即在函数中字符串变量对应位置后添加 .c_str() -
结构体综合案例2:冒泡升序排信息
设计一个包含姓名、年龄、性别的英雄结构体,将5名英雄按照年龄升序排列,并打印最终结果
#include <iostream> #include <string> using namespace std; struct Hero { string name; int age; string gender; }; int main() { struct Hero hero_arr[] = { {"刘备",25,"男"}, {"张飞",23,"男"}, {"貂蝉",18,"女"}, {"关于",24,"男"}, {"赵云",22,"男"} }; int hero_num = sizeof(hero_arr) / sizeof(hero_arr[0]); for (int i = 0; i < hero_num-1; i++) { for (int j = i + 1; j < hero_num; j++) { if (hero_arr[i].age > hero_arr[j].age) { int temp = hero_arr[i].age; hero_arr[i].age = hero_arr[j].age; hero_arr[j].age = temp; } } } for (int i = 0; i < hero_num; i++) { cout << hero_arr[i].name << "\t" << hero_arr[i].age << "\t" << hero_arr[i].gender << endl; } system("pause"); return 0; } /******************** 输出结果 **********************/ 刘备 18 男 张飞 22 男 貂蝉 23 女 关于 24 男 赵云 25 男