结构体
950 字
5 分钟
结构体
结构体类型的声明
- 结构体:一些值的集合,这些值称为成员变量
- 每个成员可以是不同类型变量
声明
struct tag{ member-list;}variable-list;
// 示例:描述学生struct Stu{ char name[20]; // 名字 int age; // 年龄 char sex[5]; // 性别 char id[20]; // 学号}; // 分号不能丢创建和初始化
#include <stdio.h>
int main(){ // 按照结构体成员的顺序初始化 struct Stu s = {"张三", 20, "男", "20230818001"};
// 按照指定的顺序初始化 struct Stu s2 = {.age = 18, .name = "lisi", .id = "20230818002", .sex = "女"}; return 0;}匿名结构体
声明时省略结构体标签
// 匿名结构体类型struct{ int a; char b; float c;}x;
struct{ int a; char b; float c;}a[20], *p;
// p = &x; // 非法!编译器认为是不同的类型结构体自引用
结构体包含同类型结构体指针
struct Node{ int data; struct Node* next; // 如果没有* 大小将会是无穷大};typedef注意事项
// 错误写法typedef struct{ int data; Node* next; // 错误!Node还未定义}Node;
// 正确写法typedef struct Node{ int data; struct Node* next;}Node;结构体内存对齐
对齐规则
- 第一个成员对齐到偏移量为0的地址处
- 其他成员对齐到对齐数的整数倍地址处
- 对齐数 = min(编译器默认对齐数,成员大小)
- VS默认值:8,Linux gcc无默认(对齐数=成员大小)
- 结构体总大小为最大对齐数的整数倍
- 嵌套结构体:嵌套的结构体成员对齐到自己的最大对齐数的整数倍处
为什么存在内存对齐
- 平台原因:不是所有硬件都能访问任意地址的数据
- 性能原因:对齐的内存访问只需一次,未对齐可能需要两次 设计建议:让占用空间小的成员尽量集中在一起
修改默认对齐数
#include <stdio.h>
#pragma pack(1) // 设置默认对齐数为1struct S{ char c1; int i; char c2;};//pack(1)时:输出 6(1+4+1)
#pragma pack() // 还原为默认对齐数//默认对齐时:输出 12(1+3填充+4+1+3填充)int main(){ printf("%d\n", sizeof(struct S)); // 输出结果会改变 return 0;}结构体传参
struct S{ int data[1000]; int num;};
// 结构体传参 - 不推荐void print1(struct S s){ printf("%d\n", s.num);}
// 结构体地址传参 - 推荐void print2(struct S* ps){ printf("%d\n", ps->num);}
int main(){ struct S s = {{1,2,3,4}, 1000}; print1(s); // 传结构体 - 开销大 print2(&s); // 传地址 - 效率高 return 0;}结构体实现位段
什么是位断
struct A{ int _a:2; // 占用2个bit int _b:5; // 占用5个bit int _c:10; // 占用10个bit int _d:30; // 占用30个bit};位段的内存分配
- 空间按需以4字节(int)或1字节(char)方式开辟
- 涉及很多不确定因素,不跨平台
位段的跨平台问题
- int位段被当成有符号数还是无符号数不确定
- 位段中最大位的数目不能确定
- 成员在内存中从左向右还是从右向左分配不确定
- 位段空间不足时,舍弃剩余位还是利用不确定
位段的应用
- 网络协议中IP数据报格式使用位段节省空间
位段使用的注意事项
- 不能对位段成员使用&操作符(字节内部的bit位没有地址)
- 不能直接用scanf给位段成员输入值
// 错误scanf("%d", &sa._b);
// 正确int b = 0;scanf("%d", &b);sa._b = b;总结
- 结构体是自定义类型的重要工具
- 内存对齐是用空间换时间的策略
- 结构体传参应传递地址以提高效率
- 位段可以节省空间但存在跨平台问题
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
多态
C/C++多态(polymorphism):即"多种形态",指同一接口表现出不同行为的能力。
2
类和对象
C/C++class 是定义类的关键字 类体中内容称为类的成员: 类中的变量 → 类的属性或成员变量 类中的函数 → 类的方法或成员函数 成员变量命名惯例:前面或后面加 或 m 开头(非强制) C++ 中 struct 也可以定义类,但推荐使用 c…
3
c语言字符与字符串函数
C/C++计算'\0'之前的字符个数 返回类型为sizet(无符号整型) 字符串必须以'\0'结束
4
红黑树封装实现mymap和myset
C/C++rbtree的泛型设计:通过第二个模板参数Value决定红黑树节点中存储的数据类型 set实例化rbtree时:Value = Key map实例化rbtree时:Value = pair
5
内存管理
C/C++栈(Stack) 存储非静态局部变量、函数参数、返回值 向下增长(从高地址向低地址) 自动分配和释放 堆(Heap) 动态内存分配区域 向上增长(从低地址向高地址) 手动管理(malloc/free, new/delete) 数据段/静态…
随机文章随机推荐

