Bootstrap

C语言第七课:结构体与联合体

一、导入

学习了C语言中的数组和字符串,这些知识帮助我们处理了数据集合和文本信息。将学习C语言中的结构体和联合体,它们是用于组织复杂数据类型的重要工具。通过结构体和联合体,我们可以更高效地管理不同类型的数据,使程序更加模块化和易于维护。

二、结构体(Structures)

(一)结构体的定义

  1. 概念

    • 结构体是一种用户自定义的数据类型,可以将不同类型的数据组合在一起。

    • 结构体中的每个数据项称为成员(或字段)。

  2. 声明与定义

    • 声明

      struct 结构体名 {
          数据类型 成员1;
          数据类型 成员2;
          // 其他成员
      };
    • 定义

      struct 结构体名 变量名;
    • 示例:

      struct Student {
          int id;
          char name[50];
          float gpa;
      };
      
      struct Student s1;

(二)访问和修改结构体成员

  1. 访问成员

    • 使用点运算符(.)访问结构体的成员。

    • 示例:

      s1.id = 101;
      strcpy(s1.name, "Alice");
      s1.gpa = 3.5;
  2. 修改成员

    • 直接通过点运算符修改成员的值。

    • 示例:

      s1.gpa = 3.7;

(三)结构体数组

  1. 定义结构体数组

    • 可以定义一个结构体数组来存储多个结构体变量。

    • 示例:

      struct Student students[5];
  2. 访问和修改结构体数组

    • 示例:

      students[0].id = 101;
      strcpy(students[0].name, "Alice");
      students[0].gpa = 3.5;
      
      students[1].id = 102;
      strcpy(students[1].name, "Bob");
      students[1].gpa = 3.8;

(四)结构体作为函数参数

  1. 传递结构体

    • 可以将结构体作为参数传递给函数。

    • 示例:

      void printStudent(struct Student s) {
          printf("ID: %d, Name: %s, GPA: %.2f\n", s.id, s.name, s.gpa);
      }
      
      int main() {
          struct Student s1 = {101, "Alice", 3.5};
          printStudent(s1);
          return 0;
      }
  2. 通过指针传递结构体

    • 通过指针传递结构体可以修改结构体的内容。

    • 示例:

      void updateGPA(struct Student* s, float newGPA) {
          s->gpa = newGPA;
      }
      
      int main() {
          struct Student s1 = {101, "Alice", 3.5};
          updateGPA(&s1, 3.7);
          printStudent(s1);
          return 0;
      }

三、联合体(Unions)

(一)联合体的定义

  1. 概念

    • 联合体是一种特殊的数据类型,允许不同的数据类型共享同一块内存。

    • 联合体的大小等于其最大成员的大小。

  2. 声明与定义

    • 声明

      union 联合体名 {
          数据类型 成员1;
          数据类型 成员2;
          // 其他成员
      };
    • 定义

      union 联合体名 变量名;
    • 示例:

      union Data {
          int i;
          float f;
          char str[20];
      };
      
      union Data d1;

(二)访问和修改联合体成员

  1. 访问成员

    • 使用点运算符(.)访问联合体的成员。

    • 示例:

      d1.i = 100;
      printf("d1.i = %d\n", d1.i);
      
      d1.f = 3.14;
      printf("d1.f = %.2f\n", d1.f);
  2. 注意

    • 联合体的成员共享同一块内存,因此修改一个成员会影响其他成员的值。

    • 示例:

      d1.i = 100;
      printf("d1.i = %d\n", d1.i); // 输出:d1.i = 100
      printf("d1.f = %.2f\n", d1.f); // 输出:d1.f = 0.00(因为内存被覆盖)

(三)联合体的应用

  1. 节省内存:联合体可以用于节省内存,特别是在嵌入式系统中。

  2. 数据交换:联合体可以用于处理不同格式的数据交换。

四、枚举类型(Enumerations)

(一)枚举类型的定义

  1. 概念

    • 枚举类型是一种用户自定义的数据类型,用于定义一组整数值的符号名称。

  2. 声明与定义

    • 声明

      enum 枚举名 {
          枚举值1,
          枚举值2,
          // 其他枚举值
      };
    • 定义

      enum 枚举名 变量名;
    • 示例:

      enum Weekday {
          MONDAY,
          TUESDAY,
          WEDNESDAY,
          THURSDAY,
          FRIDAY,
          SATURDAY,
          SUNDAY
      };
      
      enum Weekday today = MONDAY;

(二)访问和使用枚举类型

  1. 访问枚举值

    • 示例:

      printf("Today is %d\n", today); // 输出:Today is 0
  2. 枚举值的默认值

    • 枚举值默认从0开始,依次递增1。

    • 可以显式指定枚举值:

      enum Weekday {
          MONDAY = 1,
          TUESDAY,
          WEDNESDAY,
          THURSDAY,
          FRIDAY,
          SATURDAY,
          SUNDAY
      };
  3. 应用

    • 枚举类型常用于表示状态、选项等,使代码更易读和维护。

五、课堂练习

  1. 练习题

    • 定义一个结构体Person,包含姓名(字符串)、年龄(整数)和性别(字符)。

    • 定义一个结构体数组,存储3个Person信息。

    • 编写一个函数printPerson,打印一个Person的信息。

    • 编写一个联合体Data,包含一个整数、一个浮点数和一个字符数组(长度为20)。

    • 编写一个程序,演示联合体成员之间的内存共享。

  2. 参考答案

    • 结构体和函数

      #include <stdio.h>
      #include <string.h>
      
      struct Person {
          char name[50];
          int age;
          char gender;
      };
      
      void printPerson(struct Person p) {
          printf("Name: %s, Age: %d, Gender: %c\n", p.name, p.age, p.gender);
      }
      
      int main() {
          struct Person people[3] = {
              {"Alice", 25, 'F'},
              {"Bob", 30, 'M'},
              {"Charlie", 28, 'M'}
          };
      
          for (int i = 0; i < 3; i++) {
              printPerson(people[i]);
          }
      
          return 0;
      }
    • 联合体

      #include <stdio.h>
      
      union Data {
          int i;
          float f;
          char str[20];
      };
      
      int main() {
          union Data d1;
      
          d1.i = 100;
          printf("d1.i = %d\n", d1.i);
      
          d1.f = 3.14;
          printf("d1.f = %.2f\n", d1.f);
      
          strcpy(d1.str, "Hello");
          printf("d1.str = %s\n", d1.str);
      
          return 0;
      }

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;