首页 > 编程笔记

C语言结构体详解

C语言中结构体是一种自定义的数据类型,用于存储不同类型的数据,将它们组合在一起以形成一个新的数据类型。结构体允许程序员将相关数据组合成一个单一的数据结构,以便更容易地管理和操作这些数据。本文将介绍C语言结构体的基础知识、定义、声明、访问和操作等方面,并通过代码演示来加深理解。

结构体的定义和声明

在 C语言中,结构体定义的基本形式如下:

struct 结构体名 {
    数据类型 成员名1;
    数据类型 成员名2;
    ...
    数据类型 成员名n;
};

其中,结构体名表示定义的结构体类型名称,成员名表示结构体中的变量名,数据类型表示成员变量的数据类型。例如,定义一个学生结构体类型:
struct Student {
    int id;
    char name[20];
    int age;
};
在结构体定义之后,可以通过结构体类型来定义结构体变量:
struct Student s1;
也可以通过 typedef 关键字来定义结构体类型的别名,方便后续使用:
typedef struct Student {
    int id;
    char name[20];
    int age;
} Student;
使用 typedef 之后,可以直接定义结构体变量,无需再添加 struct 关键字:
Student s1;

结构体的访问和操作

结构体变量中的成员变量可以通过成员运算符 . 来访问。例如,通过 s1.id 访问结构体变量 s1 中的 id 成员变量。

结构体的成员变量也可以通过指针访问。通过 -> 操作符可以访问结构体指针所指向的成员变量。例如,定义一个指向结构体的指针 p,然后通过 p->name 访问 name 成员变量:
Student *p = &s1;
printf("%s\n", p->name); // 输出 s1 的 name 成员变量
结构体变量可以作为参数传递给函数。例如,下面的函数可以打印出结构体变量 s 的信息:
void printStudent(Student s) {
    printf("ID: %d\n", s.id);
    printf("Name: %s\n", s.name);
    printf("Age: %d\n", s.age);
}
然后可以将 s1 变量作为参数传递给 printStudent 函数来打印信息:
printStudent(s1);
结构体变量也可以通过指针作为参数传递给函数。例如,下面的函数可以修改结构体变量 s 的 age 成员变量:
void updateAge(Student *s, int age) {
    s->age = age;
}
然后可以将 s1 变量的地址作为参数传递给 updateAge 函数来修改 age 成员变量:
updateAge(&s1, 20);
printf("New age: %d\n", s1.age); // 输出修改后的 age 成员变量
结构体变量可以作为数组的元素。例如,定义一个包含多个学生信息的数组:
Student students[3] = {
    {1, "Alice", 20},
    {2, "Bob", 21},
    {3, "Charlie", 22}
};
然后可以通过数组下标和成员运算符 . 访问结构体数组中的元素:
printf("%s\n", students[1].name); // 输出第二个学生的名字 Bob
结构体变量也可以作为其他结构体的成员变量。例如,定义一个包含学生信息和成绩的结构体:
struct Grade {
    int math;
    int english;
};

struct StudentWithGrade {
    Student student;
    Grade grade;
};
然后可以定义一个 StudentWithGrade 结构体变量 s2,并访问其中的成员变量:
StudentWithGrade s2 = {{4, "David", 19}, {80, 90}};
printf("%d\n", s2.student.id); // 输出学生的 ID
printf("%d\n", s2.grade.math); // 输出数学成绩

结构体的运行结果

下面的代码演示了如何定义结构体、访问和操作结构体变量:
#include <stdio.h>
#include <string.h>

typedef struct Student {
    int id;
    char name[20];
    int age;
} Student;

void printStudent(Student s) {
    printf("ID: %d\n", s.id);
    printf("Name: %s\n", s.name);
    printf("Age: %d\n", s.age);
}

void updateAge(Student *s, int age) {
    s->age = age;
}

int main() {
    Student s1 = {1, "Alice", 18};
    printf("%s\n", s1.name); // 输出 Alice
    printf("%d\n", s1.id); // 输出 1

    Student *p = &s1;
    printf("%s\n", p->name); // 输出 Alice

    strcpy(s1.name, "Lucy");
    printf("%s\n", s1.name); // 输出 Lucy

    printStudent(s1);

    updateAge(&s1, 20);
    printf("New age: %d\n", s1.age); // 输出 20

    Student students[3] = {
        {1, "Alice", 20},
        {2, "Bob", 21},
        {3, "Charlie", 22}
    };
    printf("%s\n", students[1].name); // 输出 Bob

    StudentWithGrade s2 = {{4, "David", 19}, {80, 90}};
    printf("%d\n", s2.student.id); // 输出 4
    printf("%d\n", s2.grade.math); // 输出 80

    return 0;
}
输出结果:

Alice
1
Alice
Lucy
ID: 1
Name: Lucy
Age: 18
New age: 20

总结

结构体是一种自定义的数据类型,可以包含多个不同类型的成员变量。通过结构体,可以将相关的数据和操作封装成一个整体,方便管理和维护。结构体可以作为函数参数和返回值,也可以作为数组元素和其他结构体的成员变量。使用结构体时需要注意成员变量的访问和修改方式,可以使用成员运算符 . 或者指针和箭头运算符 -> 来访问和修改结构体成员变量。

通过本文的介绍,读者应该已经了解了 C 语言中结构体的基本概念和用法。在实际编程中,结构体是一种非常实用的工具,可以提高代码的可读性、可维护性和重用性。在设计复杂的数据结构和对象时,结构体是一个必不可少的工具。

推荐阅读