C 结构体数组
更新时间:2026-08-26。本文是
languages/c/主题入门层第 44 篇(由原《数组、字符串与结构体》拆出)。一个学生是一个结构体,一整个班就是结构体数组——结构体管"一个对象的多方面",数组管"很多个同类型对象"。两者一叠,就是现实世界的批量数据。
本文要回答的问题
- 结构体数组怎么声明和初始化?
- 怎么遍历、查找、排序一个结构体数组?
- 结构体数组作为参数传什么?
一、声明与初始化
c
struct Student {
int id;
char name[32];
float score;
};
struct Student class1[3] = {
{1001, "alice", 92.5}, // 每个元素一个花括号
{1002, "bob", 78.0},
{1003, "carol", 88.5}
};class1 是一块连续内存,3 个 Student 依次排开。访问 class1[1].name = "bob":
text
class1[0] class1[1] class1[2]
[Student ] [Student ] [Student ]
id, name, score id, name, score ...二、遍历、查找、统计
c
#include <stdio.h>
#include <string.h>
int main(void) {
struct Student class1[3] = {
{1001, "alice", 92.5}, {1002, "bob", 78.0}, {1003, "carol", 88.5}
};
int n = 3;
// 遍历打印
for (int i = 0; i < n; i++) {
printf("%d %s %.1f\n", class1[i].id, class1[i].name, class1[i].score);
}
// 查找:按姓名
for (int i = 0; i < n; i++) {
if (strcmp(class1[i].name, "bob") == 0) {
printf("找到 bob,id=%d\n", class1[i].id);
break;
}
}
// 统计:平均分
float sum = 0;
for (int i = 0; i < n; i++) sum += class1[i].score;
printf("平均 %.2f\n", sum / n);
return 0;
}模式跟普通数组遍历一模一样,只是每个元素是结构体,成员用 . 访问。"数组 + 结构体 + 循环"三件套,就是 C 处理批量数据的日常。
三、排序:qsort + 比较函数
用 qsort 按成绩排序,比较函数里访问结构体成员:
c
#include <stdlib.h>
int cmp_score(const void *a, const void *b) {
const struct Student *s1 = a;
const struct Student *s2 = b;
float diff = s1->score - s2->score;
return (diff > 0) - (diff < 0); // 转成 -1/0/1
}
qsort(class1, n, sizeof(class1[0]), cmp_score);
// class1 现在按成绩升序函数指针篇讲过 qsort 的套路,这里只是把比较对象换成结构体。换比较函数就能按 id/姓名/成绩任意排序。
四、作为函数参数
c
void print_all(const struct Student arr[], int n) { // 退化成指针!
for (int i = 0; i < n; i++) {
printf("%d %s\n", arr[i].id, arr[i].name);
}
}
int main(void) {
struct Student class1[3] = {...};
print_all(class1, 3); // 传数组名 + 长度
return 0;
}和普通数组一样:传过去是首元素地址(退化成指针),必须带长度,函数里改 arr[i].score 影响外部数组。
五、结构体数组 vs 指针数组
| 形式 | 内存 | 适用 |
|---|---|---|
struct Student arr[100] | 连续,固定每元素大小 | 数量固定、元素完整 |
struct Student *arr[100] | 每个元素是指针 | 数量动态、节省空间、可指向堆 |
指针数组的每个元素是"指向结构体的指针",配合 malloc 做动态结构体数组,是动态内存管理后的进阶玩法。
六、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| 数组越界访问成员 | UB | 边界检查 |
| 忘带长度参数 | sizeof 失效 | 显式传 n |
| 排序比较函数写错 | 排序乱 | 返回 -1/0/1 |
| 结构体拷贝大数组 | 性能差 | 传指针 |
字符串成员用 == 比较 | 永远不相等 | strcmp |
七、与本站主线衔接
- 结构体数组的内存布局与对齐,见结构体内存对齐;
- 大批量数据的排序/查找性能,见排序与查找的工程实践;
- 综合实战:学生成绩管理系统,见练习:学生成绩系统。
一句话总结
结构体数组 = 连续排布的一批结构体,arr[i].成员 访问,"数组+结构体+循环"是批量数据处理的基本盘;qsort 换比较函数就能按任意字段排序,传参记得"数组名+长度"——学会它,C 程序就开始"管理现实数据"了。