C语言就该这么学之自定义类型

本章重点

  • 结构体

结构体类型的声明

结构体的自引用

结构体内存对齐

结构体传参

结构体实现位段(位段的填充&可移植性)

  • 枚举

枚举类型的定义

枚举的优点

枚举的使用

  • 联合

联合类型的定义

联合的特点

联合大小的计算


结构体

结构体的声明

结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

结构的声明

struct tag

{

member-list;

}variable-list;

创建结构体:

eg1:

一本书(书名,价格,书号)

struct Book

{

char name[20];

int price;

char id[12];

};

eg2:

结构体全局变量与局部变量的定义:

全局变量定义在main函数之外变量名直接定义在结构体后加';'

局部变量定义在main函数之内:结构体类型加变量名。

匿名结构体类型:(不完全声明)

结构体在定义的时候没有标签 (只能使用一次)

两个相同内容的一个为结构体一个位结构体指针之间的关系:

匿名结构体指针指向匿名结构体(虽然两个结构体里面的内容一样的但是还是不能引用)

警告:编译器会把上面的两个声明当成完全不的两个同类型。所以是非法的。

结构体的自引用:

eg:

//行不通,结构体一直循环访问自己。(死递归)

正确的自引用:

位指针变量后结构体大小就方便计算(4|\8)

不是包含同类型结构体变量,而是包换同类型结构体指针

重命名:

先命名标签,再引用,再改名。

结构体初始化:

先声明,在main函数中定义,可用'.'或者->来找到要定义的变量。

结构体内存对齐:

规则:

eg:

char占一个字节所以成员大小为1,与默认对齐数比较。1<8较小值(VS的默认对齐数为8)

故char c1占一个内存空间,如图中红色区域。\

int占四个字节,所以成员大小为4,与默认对齐数比较。4<8较小值

故存放i时要从储存位置为0的位置计算,对齐到4的倍数当中。如图c1的空间加3为4所以蓝色区域为i所占的空间

double为8个字节前面c1和i正好占了8个空间,所以不需要再浪费多余空间直接可以存放。

故sizeof(s2)=16。

补:VS默认对齐数位8,Linux默认对齐数不确定。

如何计算:

求循环嵌套的结构体大小:

eg:

前面我们已近叫过普通类型的存放,我们直接讲嵌套结构体的存放:

s4结构体中最大对齐数为8,所以要按8的倍空出空间来存放,因为前一个为char类型说一要浪费7个空间来补8.且s4的内存大小为16所以存放16个空间内存。(红色区域)

因此s5的大小为8+16+8=32.

重点归纳:考虑嵌套结构体内最大对其数,而不是结构体总的内存字节和默认最小对齐数比较

内存对齐规则的原因:

按存放规则存放和挨个存放比较:

设平台每次读取的内存大小为4

按规则存放的读取c和i只需各读取一次就可以读取完。

按挨个存放i需要读两次才能读全。

总结:拿空间换时间。

如何根据才能放规则存放才能做到空间最少?

让所占空间类型小的存放在前及可作做到空间上的减小。

修改默认对齐数:

#pragma pack(num) num为要修改的对齐数

结尾在写一个pragma pack()说明只在这两个pragma区间内默认对齐数被改变,完事后再改回来。

计算结构体中某变量相对于首地址的偏移:

offsetof 头文件<stddef.h>

参数:要求的结构体,要求的结构体内部元素

结构体传参:

指针传参不会啊考虑有压栈的可能,节省的内存的空间大小。

若想防止形参改变实参可以使用const

位段:

位段内部类型位 egint a :num(数据类型,名称‘:’所占的比特的大小)。

存放规则:

先使用低比特位的数据再使用高比特为的数据(右向左)

当一块空间剩余空间内容不够下一段使用,则被浪费掉

优点:节省了内存空间

缺点:

枚举:(与define作用相同)

https://blog.csdn.net/qq_28576837/article/details/125091771

(可参考链接)

联合体:

关键字:union

元素的地址相同。

共用同一空间

联合体特点:

空间按所占空间类型最大的类型来计算。

联合体初始化:

每个成员都一样,同一时间只能用一个。

(不方便挨个填写每个成员的大小)

联合体大小的计算:

按所占空间大的类型来规定最大对齐数。

eg:


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cocobol0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值