第八章 结构体

C++结构体的使用与案例

C++开发语言基础学习

8 结构体

8.1 结构体的定义与使用

  1. 定义结构体类型(创建模版) :struct 结构体名 {结构体成员列表}

    struct Student{
        string name;
        int age;
        int score;
    }
    
  2. 创建结构体变量(根据模板创建实体)三种方式:

    • 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 关键字可以省略,但是定义结构体类型时不能省略关键字

  3. 可以将结构体 struct 结构体名 看作是用户自己创建的一种数据类型

8.2 结构体数组

  1. 定义:元素是结构体的数组

  2. 语法:struct 结构体名 数组名[元素个数] = { {} , {} , …… }

  3. 实例:

    /************** 结构体数组定义 **************/
    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 结构体指针

  1. 定义结构体指针: struct 结构体名* p = &结构体变量名

  2. 访问结构体成员: p->成员名

  3. 修改结构体成员: p->成员名 = 值

  4. 实例:

    /****************** 创建结构体变量 ********************/
    struct Student s1 = { "张三",19,100 };
    
    /****************** 创建结构体指针 ********************/
    struct Student* p = &s1;
    
    /***************** 通过指针修改结构体 ******************/
    p->age = 20;
    
    /***************** 通过指针访问结构体 ******************/
    cout << "姓名: " << p->name << "\t年龄: " << p->age << endl;
    

8.4 结构体嵌套

  1. 实例:

    struct Student {		// 定义学生结构体类型
        string name;
        int age;
        int score;
    }
    
    struct Class_grade1 {	// 定义班级结构体类型
        int class_id;
        int student_num;
        struct Student stu;	// 成员中包括学生结构体类型
    }
    

8.5 结构体做函数参数

  1. 参数传递方法:值传递、地址传递

  2. 两种传参方法的区别:值传递只在函数内部修改,不会对实际结构体产生影响;地址传递会对实际结构体的成员值产生影响

  3. 实例:

    /********************** 值传递 ************************/
    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修饰结构体

  1. 作用:避免在结构体地址传递时,函数内部对结构体内容进行的修改,也就是将传入的结构体当做“只读文件”

  2. 修饰方式: function(const struct 结构体名* p)

  3. 实例:

    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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值