第 9 節

Structures and Unions

0瀏覽次數0訪問次數--跳出率--平均停留

structure

Basic concepts of structs

Structures are a ==user-defined data type== that allows users to store different data types.

Structure definition and usage

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

There are three ways to create variables using structs:

  • struct structure name variable name
  • struct structName variableName = { member1Value, member2Value, ... };
  • When defining a structure, you can also create variables of that type simultaneously. For example, in C or C++, you can declare a structure and instantiate one or more variables in a single statement. Here's a typical way to do it:
struct Point {
    int x;
    int y;
} p1, p2;  // Creates variables p1 and p2 of type struct Point

In this example, struct Point defines a new data type with members x and y. Right after the closing brace, p1 and p2 are declared as variables of this newly defined structure type.

Example:

//结构体定义
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;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary 1: The keyword for defining a structure is struct, and it cannot be omitted.

Summary 2: The keyword struct can be omitted when creating struct variables.

Summary 3: Struct variables access members using the '.' operator

struct array

Purpose: Put custom structures into an array for easier maintenance

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

Example:

//结构体定义
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;
    }


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

struct pointer

Function: Access struct members through pointers

  • Use the -> operator to access struct attributes through a struct pointer.

Example:

//结构体定义
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;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary: Struct pointers can access members within the struct using the -> operator.

struct within struct

Function: Members of a structure can be another structure

For example: Each teacher tutors one student, with each teacher's struct containing a record of one student's struct.

Example:

//学生结构体定义
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;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Summary: Structs can contain other structs as members to solve practical problems.

Struct as function parameter

Purpose: Passing structs as parameters to functions

There are two transmission methods:

  • Pass-by-value
  • address passing

Example:

//学生结构体定义
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;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Summary: If you don't want to modify the data in the main function, use pass-by-value; otherwise, use pass-by-address.

Usage Scenarios for "const" in Structures

Purpose: Use const to prevent accidental operations.

Example:

//学生结构体定义
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;
}

Running/Observing the results: After running, the example will print variable values or addresses; address values depend on the runtime environment, so focus on observing the relative positioning and pointer changes of similar objects.

Struct Example

Case 1

Case Description:

The school is conducting graduation projects, with each teacher supervising 5 students. There are a total of 3 teachers. The requirements are as follows:

Designing structs for students and teachers, where the teacher's struct includes the teacher's name and an array holding 5 students as members.

The student members have names and exam scores, create an array to store 3 teachers, and use a function to assign values to each teacher and their respective students.

Finally, print out the teacher's data as well as the data of the students they are leading.

Example:

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;
}

Run/Observation Results: The execution results may include random numbers or time-related content, which could vary with each run. Focus on observing the generation and processing flow.

Case 2

Case Description:

Design a struct for a hero, including members for name, age, and gender; create an array of structs, storing 5 heroes in the array.

Using bubble sort algorithm, sort the heroes in the array by their age in ascending order, and finally print the sorted result.

Five heroes' information is as follows:

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

Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.

Example:

//英雄结构体
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); //打印


    return 0;
}

Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.

Struct syntax differences between C and C++

Define a struct

A struct definition consists of the keyword struct followed by the struct name, which can be defined as needed.

The struct statement defines a new data type that contains multiple members. The format of the struct statement is as follows:

struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

Access struct members

Below is a declaration of a structure type Books, with the variable book. To access a member of the structure, we use the member access operator (.). The member access operator is a period between the structure variable name and the structure member we want to access.

struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

book.book_id = 1;
strcpy(book.title,"春天");

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

typedef struct Books //Books可忽略不写
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Books_Rename;

struct Books book;   //第一种写法,不使用typedf必须加 struct 定义结构体
Books_Rename book;   //用typedef后的写法,9,11行不能共存,因为变量名相同。

book.book_id = 1;0
strcpy(book.title,"春天");

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

Pointer to a structure

You can define a pointer to a structure in a similar way to defining pointers to other types of variables, as shown below:

struct Books *struct_pointer;

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

Now, you can store the address of a structure variable in the pointer variable defined above. To find the address of a structure variable, place the & operator before the structure name, as shown below:

struct_pointer = &Book1;

Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.

To access a member of a structure using a pointer to that structure, you must use the -> operator, as shown below:

struct_pointer->title;
(*struct_pointer).title;

Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.

Structure and Function

  1. As a function parameter
struct Books
{
    ···
    int   book_id;
} book;

void fun1(Books book){
}
//通常使用指针传递
void fun2(Books *book){
}

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

  1. As a function return type

A struct in C++

  1. Definition Consistent with the above definition, the difference is that in C++, even if you do not use typedef struct to define a struct, you do not need to add struct before the variable when defining a struct variable.
//定义结构体
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
//定义结构体变量
book book1;

Run/Observation Results: This section is syntax definition-focused, typically requiring compilation together with the calling code. Pay attention to the definition method and usage location.

  1. Object-oriented struct default members and inheritance are public
struct Books
{
  public://默认
    string title;
    string author;
    string subject;
    int    book_id;
  //构造函数
   Books(string t,string author,string subject,int id){
        title = t;
        author = author;
        subject = subject;
        book_id = id;
   }
   //析构函数
   ~Books(){
    ...
   }
  //成员函数
  void fun1(){
   ...
  }
   private:
   protected:
};
//初始化结构体
Books book1("title","author","subject",1);

Run/Observation Results: This is a syntax fragment, focus on the writing style; run it after completing the context.

共用体(union)

A union is a special data type that allows you to store different data types in the same memory location. You can define a union with multiple members, but only one member can hold a value at any given time. Unions provide an efficient way to use the same memory location.

Define a union

To define a union, you must use the union statement, in a similar way to defining a structure. The union statement defines a new data type with multiple members. The format of the union statement is as follows:

union [union tag]
{
   member definition;
   member definition;
   ...
   member definition;
} [one or more union variables];

Run/Observation Results: This is a syntax fragment, focus on the writing style; run it after completing the context.

//举例:
union Type_Name
{
   int i;
   float f;
   char str1[20];
   string str2;
} object_name;

//调用方式
object_name.i = 5;
object_name.f = 6.0f;
object_name.str2 = "你好!";

Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.

Note: The memory size occupied by a union is determined by its largest member variable.

音乐页