C语言 结构体
学习struct · 难度:进阶 · +15XP
C语言 结构体详解
结构体(struct)是 C 语言中用户自定义的复合数据类型,它允许将多个不同类型的变量组合成一个逻辑整体。想象一下,你需要存储一个学生的信息——姓名(字符串)、年龄(整数)、成绩(浮点数),结构体正好可以将这些数据打包在一起,让数据的组织和操作更加方便和清晰。
结构体的定义与声明
使用 struct 关键字定义结构体类型,然后可以声明该类型的变量。结构体成员可以是任何数据类型,包括基本类型、数组、指针,甚至是另一个结构体。
#include <stdio.h>
#include <string.h>
// 定义结构体类型
struct Student {
char name[50];
int age;
float score;
int id;
};
int main() {
// 声明并初始化结构体变量
struct Student s1 = {"张三", 20, 88.5, 1001};
// 访问成员:使用点运算符 .
printf("姓名: %s
", s1.name);
printf("年龄: %d
", s1.age);
printf("分数: %.1f
", s1.score);
return 0;
}
结构体数组与指针
| 用法 | 语法 | 示例 |
|---|---|---|
| 结构体数组 | struct Student arr[10]; | 存储多个学生的信息,适合批量数据处理 |
| 结构体指针 | struct Student *p = &s1; | 通过 p->name 访问成员(箭头运算符) |
| 嵌套结构体 | 一个结构体包含另一个 | struct Date { int y, m, d; }; 嵌套在学生结构体中 |
| typedef 简写 | typedef struct {...} Student; | 去掉 struct 关键字,直接用 Student s1; |
结构体作为函数参数
结构体可以作为函数参数传递。你可以按值传递(创建副本,不改变原值)或按指针传递(传递地址,可以修改原值,且效率更高,因为避免了大结构体的复制开销)。对于大型结构体,始终推荐按指针传递。
// 按指针传递 - 更高效,可以直接修改
void updateScore(struct Student *s, float newScore) {
s->score = newScore; // 使用 -> 访问成员
}
// 按值传递 - 不会修改原值
void printStudent(struct Student s) {
printf("%s - %d岁 - %.1f分
", s.name, s.age, s.score);
}
int main() {
struct Student s1 = {"李四", 21, 75.0};
updateScore(&s1, 92.5); // 传递地址
printStudent(s1); // 输出: 李四 - 21岁 - 92.5分
return 0;
}
结构体内存对齐
编译器为了提高内存访问效率,会对结构体成员进行内存对齐。不同类型的成员之间可能会存在填充字节(padding),导致结构体的实际大小大于所有成员大小之和。使用 sizeof() 可以查看结构体的实际大小。合理安排成员的声明顺序可以减少内存浪费。
- 定义一个
Book结构体,包含书名(字符串)、作者(字符串)、价格(float)和 ISBN(整数)四个成员 - 创建包含 3 本书的结构体数组,编写函数打印所有书籍信息
- 编写函数
findMostExpensive,接收结构体数组和长度,返回价格最高的那本书的指针 - 在结构体中嵌套一个
Date结构体(出版日期),练习嵌套结构体的访问 - 使用
sizeof()检查不同成员排列顺序下的结构体大小,理解内存对齐