C++中的 结构体

目录

1结构体

1.1 概念

1.2 语法与使用

1.2.1 struct 结构体名称 变量名;

1.2.2 struct 结构体名称 变量名 = { 成员1值,成员2值...};

1.2.3 定义结构体变量时直接创建变量

1.3 结构体数组

1.4 结构体指针

1.5 结构体嵌套结构体

1.6 结构体做函数参数

1.6.1 值传递

1.6.2 址传递

1.7 结构体中使用const

1.8 示例

1.8.1 示例1

1.8.2 示例2


1结构体

1.1 概念

属于用户自定义的一种数据类型,不同于内置类型(int整型,float浮点型这种)

可在其中存储不同的数据类型

1.2 语法与使用

语法:

 struct + 名称 { 成员列表 };

举例:

 struct Student
 {
     // 成员列表
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 };

这就是一个数据类型,相当于int、double等,接下来使用该数据类型定义一个变量

1.2.1 struct 结构体名称 变量名;
     struct Student s1;  // 创建变量s1
     s1.name = "Joyce";  // 变量s1中的name赋值
     s1.age = 20;        // 变量s1中的age赋值
     s1.score = 100;        // 变量s1中的score赋值
     cout << s1.name << " " << s1.age << " " << s1.score << endl;

访问结构体中的成员,用 .符号

img

1.2.2 struct 结构体名称 变量名 = { 成员1值,成员2值...};
     struct Student s2 = { "Tatina",21,99 };
     cout << s2.name << " " << s2.age << " " << s2.score << endl;

img

1.2.3 定义结构体变量时直接创建变量
 struct Student
 {
     // 成员列表
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 }s3; // 这里直接创建变量 s3

然后是赋值,访问

     s3.name = "Rose";
     s3.age = 35;
     s3.score = 98;
     cout << s3.name << " " << s3.age << " " << s3.score << endl;

img

同时:定义完数据类型后,使用结构体数据类型创建变量时可以不写struct,定义结构体时不能

如:

     Student s4; // 而不是 struct Student s4;

1.3 结构体数组

作用:将结构体放入数组中以便使用

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

举例:

首先是结构体类型的定义

 struct Student
 {
     // 成员列表
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 };

然后使用该类型创建结构体数组

     // 创建结构体数组,并直接初始化
     struct Student StrArray[3]
     {
         {"Joyce",21,200},
         {"Tatina",20,190},
         {"Rose",35,150}
     };

打印成员

   for (int i = 0; i < 3; i++)
     {
         cout << StrArray[i].name << " " 
              << StrArray[i].age << " " 
              << StrArray[i].score << endl;
     }

img

同时,还可以在初始化后,再进行赋值

     StrArray[2] = { "Baby",3,100 }; // 赋值
     // 下面打印
     for (int i = 0; i < 3; i++)
     {
         cout << StrArray[i].name << " " << StrArray[i].age << " " << StrArray[i].score << endl;
     }

img

1.4 结构体指针

作用:使用指针访问结构体中的成员

ps:使用 操作符-> 来访问结构体

首先,对于int a=20;这样的变量a,我们创建指针是int *p=&a;

表示数据类型是int,所以用int*类型的指针

因此:

     struct Student s1 = { "Joyce",21,100 };
     struct Student* ps = &s1;

s1struct Student类型的,因此指针就是struct Student*类型的,同时,可以省略struct

    cout << ps->name << " " << ps->age << " " << ps->score << endl;

img

1.5 结构体嵌套结构体

原理:结构体中的成员可以是其他结构体

直接举例:一个老师带一个50人学生的班级。老师自己有姓名,id和年龄,以及学生结构体数组

首先是定义学生结构体类型

 struct Student
 {
     // 成员列表
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 };

然后定义老师结构体类型

 struct Teacher
 {    // 老师的成员列表
     string name;
     int id;
     int age;
     struct Student Array[50]; // 学生结构体数组
 };

下面使用这两个类型来创建变量

     Teacher T;
     T.age = 35;    T.id = 1993232913;    T.name = "Knaz"; // 老师自己的数据
     T.Array[0].age = 21;    T.Array[0].name = "Tatina";    T.Array[0].score = 98; // 学生1
     T.Array[1].age = 20;    T.Array[1].name = "Joyce";    T.Array[1].score = 100; // 学生2

下面进行访问,打印

     cout << T.age << " " << T.id << " " << T.name << endl; // 打印老师的数据
     for (int i = 0; i < 50; i++)
     {    // 打印老师里学生的数据
         cout << T.Array[i].name << " " << T.Array[i].age << " " << T.Array[i].score << endl;
     }

img

1.6 结构体做函数参数

作用:结构体作为参数向函数中传递

方式:值传递 / 址传递

举例:

首先创建结构体并创建变量并赋值

 struct Student
 {
     // 成员列表
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 };
     Student s1 = { "Joyce",21,100 };

接下来,不在主函数中使用cout来打印s1中的数据,创建专门的Print打印函数

1.6.1 值传递

 void Print1(Student s1)
 {
     s1.age = 100; // 修改age为100
     cout << s1.age <<" "<< s1.name <<" "<< s1.score; // 直接打印传过来的s1中的数据
 }

img

由此可见,在Print函数里进行修改,不会改变外面主函数的值

1.6.2 址传递

 void Print2(Student *s1) // 传过来地址,所以要指针接收
 {
     s1->age = 200; // 修改age为200
     cout << s1->age << " " << s1->name << " " << s1->score; // 直接打印传过来的s1中的数据
 }

img

可以看到,主函数中age也被修改

1.7 结构体中使用const

作用:使用const防止误改数据

举例

定义结构体并创建变量与初始化

 struct Student
 {
     string name;  // 名字
     int age;      // 年龄
     int score;      // 分数
 };
     Student s1 = { "Joyce",21,100 };

接下来使用值传递Print1打印函数来查看s1中的数据

 void Print1(Student s1)
 {
     s1.age = 100;
     cout << s1.age <<" "<< s1.name <<" "<< s1.score;
 }

使用的是值传递,不会修改数据

但是,值传递的原理是拷贝一份数据的副本出来。当数据有成千上万份时,拷贝将会占用大量内存空间,降低运行效率。因此,我们采用址传递,这样,无论结构体中有多少数据,传过来并接收的只是一个指针,只需要4/8个字节空间

使用址传递:

 void Print2(Student *s1)
 {
     s1->age = 200;
     cout << s1->age << " " << s1->name << " " << s1->score;
 }

不过,由于是址传递,如果里面有修改的操作,将使外面的数据发生改变,而我们本意并不想改变只是print打印数据。

所以,在此基础上,我们在接收参数的地方加上const

 void Print2(const Student *s1) // 加上const
 {
    // s1->age = 200;
     cout << s1->age << " " << s1->name << " " << s1->score;
 }

这时,s1将无法被修改,若有修改的操作出现将直接报错,避免了对数据的误修改

1.8 示例

1.8.1 示例1

创建一个有3名老师的数组,每位老师是一个包含名字和学生结构体的结构体,学生结构体中有名字和分数。

学生与老师结构体:

 struct Student    // 学生结构体
 {
     string Sname;
     int score;
 };
 struct Teacher    // 老师结构体
 {
     string Tname;
     struct Student Sarray[5];
 };

给学生与老师赋值的函数

 void AllocatorSpace(Teacher Tarray[], int size)
 {
     string NameSeed = "ABCDE";
     for (int i = 0; i < size; i++)
     {
         // 给老师名字赋值
         Tarray[i].Tname = "Teacher_";
         Tarray[i].Tname += NameSeed[i];
         // 给老师的学生赋值
         for (int j = 0; j < 5; j++)
         {
             // 姓名赋值
             Tarray[i].Sarray[j].Sname = "Student_";
             Tarray[i].Sarray[j].Sname += NameSeed[j];
             // 成绩赋值
             int random = rand() % 61 + 40;    
                     // 代表随机数40~100,不+40,则是0~60,不过要提前加随机数种子
             Tarray[i].Sarray[j].score = random;
         }
     }
 }

打印函数

 void Print(Teacher Tarray[],int size)
 {
     for (int i = 0; i < size; i++)
     {  // 先打印老师名字
         cout << Tarray[i].Tname << endl;
         for (int j = 0; j < 5; j++)
         { // 再打印学生数据
             cout << "\t";
             cout << Tarray[i].Sarray[j].Sname << " ";
             cout << Tarray[i].Sarray[j].score << endl;
         }
         cout << endl;
     }
 }

主函数

     srand((unsigned int)time(NULL));    // 随机数种子
 ​
     Teacher Tarray[3];
     int size = sizeof(Tarray) / sizeof(Tarray[0]);
 ​
     AllocatorSpace(Tarray, size);
     Print(Tarray,size);

1.8.2 示例2

创建一个包含5个人的结构体,内有姓名、性别与年龄,按照年龄大小进行升序排列,并打印输出

定义结构体

 struct Hero
 {
     string name;
     int age;
     string sex;
 };

主函数内创建结构体数组并赋值

     struct Hero HeroArray[5]
     {
         {"刘备",23,"男"},
         {"关羽",22,"男"},
         {"张飞",20,"男"},
         {"赵云",21,"男"},
         {"貂蝉",19,"女"}
     };
     int size = sizeof(HeroArray) / sizeof(HeroArray[0]);

进行冒泡排序,以及打印函数

 void BubbleSort(Hero HeroArray[], int size)
 {
 ​
     for (int i = 0; i < size - 1; i++)
     {
         for (int j = 0; j < size - i - 1; j++)
         {
             if (HeroArray[j].age > HeroArray[j + 1].age)
             {
                 Hero tmp = HeroArray[j];
                 HeroArray[j] = HeroArray[j + 1];
                 HeroArray[j + 1] = tmp;
             }
         }
     }
 }
 void Print(Hero HeroArray[], int size)
 {
     for (int i = 0; i < size; i++)
     {
         cout << HeroArray[i].name << " " << HeroArray[i].age << " " << HeroArray[i].sex << endl;
     }
     cout << endl;
 }

主函数

     Print(HeroArray, size);
     cout << "排序后:" << endl << endl;
 ​
     BubbleSort(HeroArray, size);
     Print(HeroArray,size);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值