自定义类型

目录

一、结构体

1.结构体的定义

2.结构体的自引用

3.结构体的初始化

4.结构体的内存对齐

二、枚举

1.枚举类型

2.枚举相较于define的优势

三、联合体

1.联合体的定义

2.联合体大小的计算

3.联合体的应用———大小端的判断

1-1.结构体的定义

结构体是c语言32个关键字的其中之一,结构体是不同类型数据的集合,这些类型称为结构体变量。

1-2结构体声明

由结构体关键字+结构体标签组成

例如描述一个学生就可以使用结构体。

除此方式外,结构体还有特殊的声明,成为结构体匿名类型

比如上述学生结构体关键字可以省略

1-3结构体的自引用

1-4结构体变量的定义和初始化

 同时第一个结构体变量s为全局变量,第二个结构体变量s为局部变量。

 

1-5结构体的内存对齐

结构体的内存对齐一直是一大热点

那么结构体究竟是如何对齐呢?

先看上面两个例子:

如果 没有学过结构体的内存对齐应该是这样做的

 我们都知道在32位中int类型是四个字节,char类型是一个字节,如果这样算的话sn1,sn2都是六个字节,那么结果究竟是多少呢,我们让代码运行一下,结果如下:

而最后的结果为8 12;

为什么一定要存在对齐呢?为什么不能像我们想的那样运行呢?主要有两个原因:

1.平台原因:

不是所有的平台都能访问任意地址的数据;

2.性能原因:

栈上的数据结构应该尽可能地去对齐,如果没有对齐的话,处理器需要对其进行两次访问,但是如果对齐的话,只需进行一次访问(减少了运行时间,提高效率)

 知道了对齐的原因,我们就应该了解一下对齐的规则;

1.第一个成员永远对齐到结构体起始位置为0的偏移处

2.第二个成员要对齐到【某个对齐数】的整数倍的偏移处

对齐数:结构体成员自身的大小和默认对齐数的较小值;

vs默认偏移数为8;

lunix环境不设对齐数(对齐数是结构体成员自身的大小);

3结构体的总大小必须是最大对齐数的整数倍。每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数

4.如果有嵌套结构体的情况,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍;

 先分析sn1,假设起始位置0为如图所示位置,首先int是四个字节向后填充四个黄色(一格代表一个字节),而char的较小对齐数为1(char为1,默认对齐数为8,较小值为1)起始位置4是1的整数倍,结束时5也是对齐数1的整数倍,填充一格,而在最后偏移量停留在6,最大对齐数为4(4,1,1较大值为4),所以还得填充两格到偏移量为的位置,所以社sn1的大小为8;

sn2

 sn2首先是char所以占一个字节,而后面int四个字节,所以必须从4的整数倍开始,所以首先从偏移量为4处开始,偏移量为8刚好结束,同理char又是一个字节,占一个字节,最后在偏移量为9处结束,偏移量结束必须是最大对齐数4的整数倍,所以在12处结束,所以sn2占12个字节

2-1枚举类型

枚举顾名思义就是列举,把枚举类型可能的值一一列举出来;

例如下图:

 enum color就是枚举类型,而BLUE,GREEN,RED就是枚举常量,并且枚举常量的值都是从零开始,依次递增,当然也可以自己定义枚举常量的值;

同时也要注意!!

枚举常量最后一个值之前的值结尾都是逗号,最后一个结尾无任何符号;

 

同时也会有这样的疑问,这不是和#define的作用差不多嘛?什么情况下用#define,什么情况下用枚举呢?

大多数情况下用枚举比较好,有以下几点原因:

1.增加代码的可读性与可维护性;

2.和define定义的标识符比较枚举定义的标识符有类型检查更加严谨;

3.防止命名污染;

4.便于调试;

3-1联合体的定义:

联合体的成员共用同一块空间。

 3-2联合体的特点

1.所有成员共用一块地址

 

 

2.联合体大小的计算:

(1).联合体的大小至少是最大成员的大小;

(2).当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍;

根据上面例子,int最小对齐数是4,char的最小对齐数是1,所以最大对齐数是4,联合体最大成员的大小是4,刚好是最大成员的整数倍;

 

3-3联合体的应用——大小端的判断

1.常规方法——强制类型转换

知识:1.大端:高位字节序存在低地址,地位字节序反之;

2.小端:低位字节序存在低地址,高位字节序反之;

 2.联合体

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值