【C++核心】结构体、共用体详解

简介: 这篇文章详细讲解了C++中结构体和共用体的概念、定义、使用场景和案例,包括结构体的创建、数组、指针、嵌套、函数参数传递,以及共用体的特点和应用实例。

一. 结构体

1.1 结构体基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

1.2 结构体定义和使用

语法: struct 结构体名 { 结构体成员列表 };

通过结构体创建变量的方式有三种:

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = { 成员1值 , 成员2值…}
  • 定义结构体时顺便创建变量

示例:

#include<iostream>
#include<string>
using namespace std;

//结构体定义
struct student
{
   
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
}stu3; //结构体变量创建方式3 


int main() {
   

    //结构体变量创建方式1
    struct student stu1; //struct 关键字可以省略

    stu1.name = "张三";
    stu1.age = 18;
    stu1.score = 100;
    cout << "姓名:" << stu1.name << " 年龄:" << stu1.age  << " 分数:" << stu1.score << endl;

    //结构体变量创建方式2
    struct student stu2 = {
    "李四",19,60 };
    cout << "姓名:" << stu2.name << " 年龄:" << stu2.age  << " 分数:" << stu2.score << endl;

    stu3.name = "王五";
    stu3.age = 18;
    stu3.score = 80;
    cout << "姓名:" << stu3.name << " 年龄:" << stu3.age  << " 分数:" << stu3.score << endl;

    return 0;
}
AI 代码解读

总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.‘’ 访问成员

1.3 结构体数组

作用: 将自定义的结构体放入到数组中方便维护

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

示例:

#include<iostream>
#include<string>
using namespace std;

//结构体定义
struct student
{
   
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
}

int main() {
   

    //结构体数组
    struct student arr[3]=
    {
   
        {
   "张三",18,80 },
        {
   "李四",19,60 },
        {
   "王五",20,70 }
    };

    for (int i = 0; i < 3; i++)
    {
   
        cout << "姓名:" << arr[i].name << " 年龄:" << arr[i].age << " 分数:" << arr[i].score << endl;
    }

    system("pause");
    return 0;
}
AI 代码解读

1.4 结构体指针

作用: 通过指针访问结构体中的成员,利用操作符 -> 可以通过结构体指针访问结构体属性

示例:

#include<iostream>
#include<string>
using namespace std;

//结构体定义
struct student
{
   
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
};


int main() {
   

    struct student stu = {
    "张三",18,100, };

    struct student * p = &stu;

    p->score = 80; //指针通过 -> 操作符可以访问成员

    cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;

    return 0;
}
AI 代码解读

总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员

1.5 结构体嵌套结构体

作用: 结构体中的成员可以是另一个结构体

例如: 每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体

示例:

#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 t1;
    t1.id = 10000;
    t1.name = "老王";
    t1.age = 40;

    t1.stu.name = "张三";
    t1.stu.age = 18;
    t1.stu.score = 100;

    cout << "教师 职工编号: " << t1.id << " 姓名: " << t1.name << " 年龄: " << t1.age << endl;

    cout << "辅导学员 姓名: " << t1.stu.name << " 年龄:" << t1.stu.age << " 考试分数: " << t1.stu.score << endl;

    return 0;
}
AI 代码解读

总结: 在结构体中可以定义另一个结构体作为成员,用来解决实际问题

1.6 结构体做函数参数

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

传递方式有两种:值传递地址传递

示例:

#include<iostream>
#include<string>

using namespace std;

//学生结构体定义
struct student
{
   
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
};

//值传递
void printStudent(student stu )
{
   
    stu.age = 28;
    cout << "子函数中 姓名:" << stu.name << " 年龄: " << stu.age  << " 分数:" << stu.score << endl;
}

//地址传递
void printStudent2(student *stu)
{
   
    stu->age = 28;
    cout << "子函数中 姓名:" << stu->name << " 年龄: " << stu->age  << " 分数:" << stu->score << endl;
}

int main() {
   

    student stu = {
    "张三",18,100};
    //值传递
    printStudent(stu);
    cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age << " 分数:" << stu.score << endl;

    cout << endl;

    //地址传递
    printStudent2(&stu);
    cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age  << " 分数:" << stu.score << endl;

    return 0;
}
AI 代码解读

总结:如果不想修改主函数中的数据,用值传递,反之用地址传递

1.7 结构体中 const使用场景

作用: 用const来防止误操作

示例:

#include<iostream>
#include<string>
using namespace std;

//学生结构体定义
struct student
{
   
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
};

//const使用场景
void printStudent(const student *stu) //加const防止函数体中的误操作
{
   
    //stu->age = 100; //操作失败,因为加了const修饰
    cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;

}

int main() {
   

    student stu = {
    "张三",18,100 };

    printStudent(&stu);

    return 0;
}
AI 代码解读

1.8 结构体案例

1.8.1 案例1

案例描述:

学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:

  • 设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员;
  • 学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
  • 最终打印出老师数据以及老师所带的学生数据。

示例:

#include<iostream>
#include<string>
#include<ctime>
using namespace std;

struct Student
{
   
    string name;
    int score;
};
struct Teacher
{
   
    string name;
    Student sArray[5];
};

void allocateSpace(Teacher tArray[] , int len)
{
   
    string tName = "教师";
    string sName = "学生";
    string nameSeed = "ABCDE";
    for (int i = 0; i < len; i++)
    {
   
        tArray[i].name = tName + nameSeed[i];

        for (int j = 0; j < 5; j++)
        {
   
            tArray[i].sArray[j].name = sName + nameSeed[j];
            tArray[i].sArray[j].score = rand() % 61 + 40;
        }
    }
}

void printTeachers(Teacher tArray[], int len)
{
   
    for (int i = 0; i < len; i++)
    {
   
        cout << tArray[i].name << endl;
        for (int j = 0; j < 5; j++)
        {
   
            cout << "\t姓名:" << tArray[i].sArray[j].name << " 分数:" << tArray[i].sArray[j].score << endl;
        }
    }
}

int main() {
   

    srand((unsigned int)time(NULL)); //随机数种子 头文件 #include <ctime>

    Teacher tArray[3]; //老师数组

    int len = sizeof(tArray) / sizeof(Teacher);

    allocateSpace(tArray, len); //创建数据

    printTeachers(tArray, len); //打印数据

    return 0;
}
AI 代码解读
1.8.2 案例2

案例描述:

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

五名英雄信息如下:

        {"刘备",23,"男"},
        {"关羽",22,"男"},
        {"张飞",20,"男"},
        {"赵云",21,"男"},
        {"貂蝉",19,"女"},
AI 代码解读

示例:

#include<iostream>
#include<string>
using namespace std;

//英雄结构体
struct hero
{
   
    string name;
    int age;
    string sex;
};
//冒泡排序
void bubbleSort(hero arr[] , int len)
{
   
    for (int i = 0; i < len - 1; i++)
    {
   
        for (int j = 0; j < len - 1 - i; j++)
        {
   
            if (arr[j].age > arr[j + 1].age)
            {
   
                hero temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
//打印数组
void printHeros(hero arr[], int len)
{
   
    for (int i = 0; i < len; i++)
    {
   
        cout << "姓名: " << arr[i].name << " 性别: " << arr[i].sex << " 年龄: " << arr[i].age << endl;
    }
}

int main() {
   

    struct hero arr[5] =
    {
   
        {
   "刘备",23,"男"},
        {
   "关羽",22,"男"},
        {
   "张飞",20,"男"},
        {
   "赵云",21,"男"},
        {
   "貂蝉",19,"女"},
    };

    int len = sizeof(arr) / sizeof(hero); //获取数组元素个数

    bubbleSort(arr, len); //排序

    printHeros(arr, len); //打印

    system("pause");
    return 0;
}
AI 代码解读

二. 共用体(union)

union即为联合,它是一种特殊的类。通过关键字union进行定义,一个union可以有多个数据成员。例如

union Token{
   
   char cval;
   int ival;
   double dval;
};
AI 代码解读

以上代码定义了一个名为Token的联合,该联合中包含了3个数据成员。

2.1 共用体的优点

共用体的优点如下:

1、分段使用
2、节省空间:对于有几个变量不会在某一段时刻同时出现,那么我们利用共用体,可以节省内存空间。
3、代替强类型转换。例如:在网络编程中,经常会用到传入一串数据,这些数据将会以参数的形式传递给不同的函数。因此可以用到共用体,让共用体里面全都是函数指针,在同一时刻指向不同的函数。因此来提高编程效率,以及节省空间。

2.2 union的局限性

union中的对象成员,不能有构造函数、析构函数、重载的复制赋值运算符;对象成员的对象成员也不能有,依此类推
union不能继承

2.3 union案例

使用union保存成绩信息,并输出

#include <iostream>
using namespace std;

class ExamInfo {
   

public:
    ExamInfo(string n, char g):name(n),mode(GRADE),grade(g){
   }
    ExamInfo(string n, bool p):name(n),mode(PASS),grade(p){
   }
    ExamInfo(string n, int p):name(n),mode(PERCENTAGE),grade(p){
   }

    void show();

private:
    string name;
    enum {
   GRADE, PASS, PERCENTAGE} mode;
    union {
   
        char grade;
        bool pass;
        int percent;
    };

};

void ExamInfo::show() {
   
    cout << name << ": ";

    switch(mode) {
   
        case GRADE: cout << grade;break;
        case PASS: cout << pass ? "PASS" : "FAIL";break;
        case PERCENTAGE: cout << percent;break;
    }

    cout << endl;
}

int main() {
   

    ExamInfo examInfo1("English", 'B');
    ExamInfo examInfo2("Calculus", true);
    ExamInfo examInfo3("C++ Programming", 85);

    examInfo1.show();       // English: B
    examInfo2.show();       // Calculus: 1
    examInfo3.show();       // C++ Programming: 85

    return 0;
}
AI 代码解读
目录
打赏
0
4
4
0
70
分享
相关文章
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
389 0
|
9月前
|
C++
C++系列十四:结构体
C++系列十四:结构体
|
9月前
|
C++
.C++中结构体数组docx
.C++中结构体数组docx
58 0
|
6月前
|
C++
c++学习笔记07 结构体
C++结构体的详细学习笔记07,涵盖了结构体的定义、使用、数组、指针、嵌套、与函数的交互以及在结构体中使用const的示例和解释。
58 0
|
5月前
|
C++
继续更新完善:C++ 结构体代码转MASM32代码
继续更新完善:C++ 结构体代码转MASM32代码
|
6月前
|
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
64 0
C++一分钟之-结构体与联合体(Union)
【6月更文挑战第20天】在C++中,结构体(struct)用于组合多种数据类型形成复合类型,成员变量占用独立内存,适合存储不同类型且同时有效的数据。联合体(union)则让所有成员共享同一内存,适合节省空间和进行低级别类型转换,但需小心数据覆盖。通过`struct`和`union`,程序员能构建更灵活的代码,但也需留意内存对齐和数据管理等问题。
118 2
|
9月前
|
C++
C++程序中的结构体类型
C++程序中的结构体类型
91 1