基本类型只能表示单个值,数组要求元素类型相同。若要在一个变量中组合多种相关数据(例如学生的学号、姓名与成绩),可使用结构体(struct)将多个成员聚合为一条记录,便于传递与组织复杂数据。

结构体的定义与用途

结构体是用户自定义的复合类型,各成员可具有不同类型。常见用途包括:

  • 将相关字段打包为一条记录,作为函数的一个实参传递。
  • 描述链表、树等数据结构的节点内容。
  • 与文件读写配合,表示持久化或交换用的记录格式。

例如用结构体表示平面上的点:

struct point {
    int x;
    int y;
};

定义末尾的分号不可省略。定义变量并访问成员:

struct point p;
p.x = 10;
p.y = 5;
/* draw(p);  一个实参即可携带两个坐标 */

若不用结构体,往往需要多个同类型参数才能表达同一含义:

int x = 10;
int y = 5;
/* draw(x, y); */

通过点运算符 . 访问结构体对象的成员。

struct point p int x = 10(4 字节) int y = 5(4 字节) 用 p.x、p.y 分别访问这两个成员
结构体对象包含多个命名成员,通过点运算符分别访问。

typedef 与类型别名

反复书写 struct point 较为繁琐,可用 typedef 定义别名(详见typedef):

typedef struct {
    int x;
    int y;
} point;

point p;
p.x = 10;
p.y = 5;

结构体成员也可为指针,用于保存字符串或指向其他结构体:

C 语言 typedef 结构体示例运行
typedef struct {
    char *brand;
    int model;
} vehicle;

vehicle mycar;
mycar.brand = "Ford";
mycar.model = 2007;

结构体指针与箭头运算符

指向结构体的指针通过解引用访问成员,-> 为常用简写(参见按地址传参):

C 语言结构体指针访问示例运行
point p;
point *ptr = &p;

p.x = 1;
(*ptr).x = 2;
ptr->x = 3;   /* 等价于 (*ptr).x */

对结构体对象使用 .;对结构体指针使用 ->。

声明、初始化与 sizeof

C 语言结构体示例运行
#include <stdio.h>

struct Student {
    int rollNo;
    float height;
    char firstLetter;
};

int main(void) {
    struct Student stu1;
    stu1.rollNo = 21;
    stu1.height = 1.75f;
    stu1.firstLetter = 'X';
    printf("学号 %d,身高 %.2f,姓名首字母 %c\n",
           stu1.rollNo, stu1.height, stu1.firstLetter);

    struct Student stu2 = {30, 1.82f, 'M'};
    printf("第二个学生学号 %d\n", stu2.rollNo);

    printf("一个 Student 占 %zu 字节\n", sizeof(struct Student));
    return 0;
}

结构体与数组的对比

  • 数组:元素类型相同、内存连续,适合同质数据的批量存储。
  • 结构体:成员类型可不同;因内存对齐,sizeof 往往大于各成员大小之和。

下一节介绍共用体,其与结构体在内存布局上的差异是二者区分的核心。