当前位置: 首页 > news >正文

C语言:结构体

结构体

假设我们要记录一个学生的信息:
- 姓名(字符串)
- 学号(整数)
- 成绩(浮点数)
- 性别(字符)

如果用普通变量来存,我们需要这样写:
```c
int sno[30];
char name[30][20];
float score[30];
char sex[30];
```

这样写很麻烦,而且数据之间没有关联性。结构体就是为了解决这个问题而生的!

## 什么是结构体?

结构体就像是一个"盒子",可以把不同类型的数据打包在一起。我们可以自己定义这个盒子里装什么。

定义结构体

```c
struct student {
int sno;        // 学号
char name[20];  // 姓名
float score;    // 成绩
char sex;       // 性别
};  // 注意这里要有分号
```

这样就定义了一个叫`student`的结构体类型,它包含4个成员。

使用结构体

定义好结构体类型后,就可以像使用int、float那样使用它了:

```c
// 定义结构体变量
struct student stu1;  // 定义一个学生变量
struct student class[30];  // 定义一个学生数组
struct student *p;    // 定义一个指向学生的指针
```

访问结构体成员

使用点号`.`来访问结构体成员:

```c
stu1.sno = 1001;
strcpy(stu1.name, "张三");
stu1.score = 89.5;
stu1.sex = 'M';
```

结构体初始化

可以像数组一样初始化:

```c
struct student stu2 = {1002, "李四", 92.0, 'F'};
```

 结构体赋值

同类型的结构体可以直接赋值:

```c
struct student stu3 = stu2;  // 把stu2的值赋给stu3
```

 结构体与函数

结构体可以作为函数参数和返回值:

```c
// 打印学生信息
void printStudent(struct student s) {
printf("学号:%d 姓名:%s 成绩:%.1f 性别:%c\n", 
s.sno, s.name, s.score, s.sex);
}

// 输入学生信息
void inputStudent(struct student *p) {
scanf("%d %s %f %c", &p->sno, p->name, &p->score, &p->sex);
}
```

注意:使用指针传递效率更高(`->`是指向成员的运算符)。

结构体大小

结构体的大小不是简单地把所有成员大小相加,因为存在"内存对齐"的问题。计算大小时要考虑:
1. 每个成员放在它的"自然边界"上
2. 整个结构体大小要是最大成员大小的整数倍

例如:
```c
struct demo1 {
char a;  // 1字节
char b;  // 1字节
int c;   // 4字节
};  // 总共8字节

struct demo2 {
char a;  // 1字节
int b;   // 4字节
char c;  // 1字节
};  // 总共12字节(因为有对齐填充)
```

共用体(union)

共用体让多个变量共享同一块内存,可以节省空间:

```c
union demo {
char a;
short b;
int c;
};  // 大小是4字节(最大的成员大小)
```

共用体常用于:
1. 节省内存空间
2. 检测电脑是大端还是小端存储

枚举(enum)

枚举用来定义一组有限的常量:

```c
enum Weekday {
MON, TUE, WED, THU, FRI, SAT, SUN
};

enum Weekday today = WED;
```

枚举让代码更易读,编译器也会做更好的检查。

实际应用

结构体非常适合用来描述复杂对象,比如:
- 学生管理系统
- 网络协议
- 游戏中的角色属性
- 图形界面中的控件

练习建议

1. 定义一个学生结构体,输入3个学生信息并计算平均分
2. 写一个函数找出成绩最高的学生
3. 使用qsort对结构体数组排序
4. 尝试用共用体检测你的电脑是大端还是小端存储

结构体是C语言中非常重要的概念,掌握了它,你就能更好地组织和管理复杂数据了!

http://www.dtcms.com/a/321147.html

相关文章:

  • mac电脑解决在不同项目需要频繁手动切换node版本的困扰
  • Autosar AP功能组状态和模型进程是否预定义后不改变了?
  • Mac 电脑放在环境变量中的通用脚本
  • 从浅拷贝到深拷贝:C++赋值运算符重载的核心技术
  • SITIME汽车时钟发生器Chorus保障智能汽车安全
  • 《告别Bug!GDB/CGDB调试实战指南》
  • 「iOS」————优先级反转
  • 解决Docker部署的MySQL8错误日志里面的 mbind: Operation not permitted 问题
  • 构建安全 Web 应用:从用户认证与授权到 JWT 原理解析
  • python使用python-docx自动化操作word
  • 【杂谈】-逆缩放悖论:为何更多思考会让AI变“笨“?
  • Numpy科学计算与数据分析:Numpy布尔索引与花式索引实战
  • 一种对白点进行多重加权并利用三角剖分插值微调白平衡增益的白平衡矫正算法
  • RAG问答系统:Spring Boot + ChromaDB 知识库检索实战
  • 3D Tiles 格式中,Bounding Volum
  • 基于AutoDL平台的3D_Gaussian_Splatting初体验
  • 在 Vue 中使用 ReconnectingWebSocket实现即时通讯聊天客服功能
  • 2025 前端真实试题-阿里面试题分析
  • 关于数据结构6-哈希表和5种排序算法
  • Maptalks vs Cesium
  • 【最新版】2025年搜狗拼音输入法
  • “电子合同”为什么会出现无效的情况?
  • OpenCV cv2.flip() 函数详解与示例
  • 深入理解 Java AWT Container:原理、实战与性能优化
  • ORACLE看当前连接数的方法
  • 柠檬笔试——野猪骑士
  • 南方略咨询与与清源科技正式启动国际市场GTM流程规划咨询项目!!!
  • 汽车电子:现代汽车的“神经中枢“
  • Eyevinn 彻底改变开源部署模式
  • 小孙学变频学习笔记(十三)电动机参数的自动测量 矢量控制的转速反馈