C语言教程:结构体与联合体 - 5.2 结构体数组

在C语言中,结构体(struct)和联合体(union)是用于将不同类型的数据组合在一起的强大工具。结构体数组是结构体的一个重要扩展,它允许我们创建一个结构体的集合,便于管理和操作相关的数据。在本节中,我们将深入探讨结构体数组的定义、使用、优缺点以及注意事项。

1. 结构体数组的定义

结构体数组是由多个相同类型的结构体组成的数组。每个结构体可以包含不同类型的数据,结构体数组则允许我们以数组的形式存储多个结构体实例。

1.1 定义结构体

首先,我们需要定义一个结构体。例如,假设我们要存储学生的信息,包括姓名、年龄和成绩:

#include <stdio.h>
#include <string.h>

#define MAX_STUDENTS 100

typedef struct {
    char name[50];
    int age;
    float grade;
} Student;

1.2 定义结构体数组

接下来,我们可以定义一个结构体数组来存储多个学生的信息:

Student students[MAX_STUDENTS];

2. 结构体数组的使用

2.1 初始化结构体数组

我们可以在定义结构体数组时进行初始化:

Student students[3] = {
    {"Alice", 20, 85.5},
    {"Bob", 21, 90.0},
    {"Charlie", 19, 78.0}
};

2.2 访问结构体数组的元素

我们可以通过数组索引访问结构体数组中的元素,并使用点运算符访问结构体的成员:

for (int i = 0; i < 3; i++) {
    printf("Name: %s, Age: %d, Grade: %.2f\n", students[i].name, students[i].age, students[i].grade);
}

2.3 修改结构体数组的元素

我们可以直接通过索引和点运算符修改结构体数组中的元素:

students[0].grade = 88.0; // 修改Alice的成绩

2.4 动态分配结构体数组

如果我们不知道结构体数组的大小,可以使用动态内存分配:

#include <stdlib.h>

int main() {
    int n;
    printf("Enter number of students: ");
    scanf("%d", &n);

    Student *students = (Student *)malloc(n * sizeof(Student));
    if (students == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    // 进行数据输入和处理...

    free(students); // 释放内存
    return 0;
}

3. 优点与缺点

3.1 优点

  • 组织性:结构体数组使得相关数据的组织更加清晰,便于管理。
  • 可扩展性:可以轻松地添加新的结构体成员或增加结构体数组的大小。
  • 类型安全:结构体提供了类型安全,避免了使用简单数组时可能出现的类型混淆。

3.2 缺点

  • 内存占用:结构体数组在内存中占用的空间可能较大,尤其是当结构体成员较多时。
  • 固定大小:静态定义的结构体数组大小在编译时确定,可能导致内存浪费或不足。
  • 复杂性:对于初学者来说,结构体和结构体数组的概念可能较为复杂。

4. 注意事项

  • 内存管理:使用动态分配时,务必在不再使用时释放内存,以避免内存泄漏。
  • 数组越界:访问结构体数组时,确保索引在有效范围内,以避免未定义行为。
  • 结构体对齐:不同编译器可能对结构体的内存对齐有不同的处理,可能会影响内存使用和性能。

5. 示例代码

以下是一个完整的示例,展示了如何使用结构体数组来管理学生信息:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STUDENTS 100

typedef struct {
    char name[50];
    int age;
    float grade;
} Student;

void printStudents(Student *students, int count) {
    for (int i = 0; i < count; i++) {
        printf("Name: %s, Age: %d, Grade: %.2f\n", students[i].name, students[i].age, students[i].grade);
    }
}

int main() {
    int n;
    printf("Enter number of students: ");
    scanf("%d", &n);

    if (n > MAX_STUDENTS) {
        printf("Cannot exceed maximum number of students (%d).\n", MAX_STUDENTS);
        return 1;
    }

    Student *students = (Student *)malloc(n * sizeof(Student));
    if (students == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        printf("Enter name, age and grade for student %d: ", i + 1);
        scanf("%s %d %f", students[i].name, &students[i].age, &students[i].grade);
    }

    printf("\nStudent Information:\n");
    printStudents(students, n);

    free(students); // 释放内存
    return 0;
}

结论

结构体数组是C语言中一个非常有用的特性,它允许我们以结构化的方式管理相关数据。通过合理使用结构体数组,我们可以提高代码的可读性和可维护性。在使用时,注意内存管理和数组越界等问题,以确保程序的稳定性和安全性。希望本节内容能帮助你更好地理解和使用结构体数组。