C语言自定义类型

C语言自定义类型,第1张

C语言自定义类型

之前的博客中有介绍过关于结构体的内容,但介绍的并不详细,这篇在其基础上更加详细的介绍结构体和其它的自定义类型

目录

1.结构体

1.1结构体特殊声明

1.2结构体引用

1.2.1引用其他结构体

1.2.2自引用

1.3结构体的大小

1.3.1内存对齐和偏移量

1.3.2存在内存对齐的原因

1.3.3默认对齐数的修改

 2.位段

2.1位段的内存分配

3.枚举

3.1枚举的定义

3.2枚举的声明

3.3枚举的大小

4.联合(共用体)

4.1联合定义

4.2联合的声明

4.3联合的大小

 


1.结构体

之前已经介绍过结构体的定义、声明和使用,在这就直接跳过。原文链接:C语言结构体_鹰不泊wyk的博客-CSDN博客

1.1结构体特殊声明

结构体在声明的时候可以不完全声明:

struct
{
int a;
char b;
float c;
}x;  //但变量只能在这里定义,而且这个结构体只能使用一次,指针也无法指向这个结构体

这种结构体类型就是匿名结构体

1.2结构体引用

既然结构体中成员变量的数据类型不同,结构体本身又作为变量,那么结构体中自然可以有结构体作为成员

1.2.1引用其他结构体
struct Node
{
int data;
struct book p;
};
1.2.2自引用

结构体自引用不能按照上述方法引用,如果按照上述方法引用,结构体的大小是无法计算的

正确自引用方法:

struct Node
{
int data;
struct Node* next;
};
1.3结构体的大小 1.3.1内存对齐和偏移量

结构体的大小的计算和二者有关

在结构体中,结构体的对齐规则如下:

1.第一个成员在偏移量为0的地方

2.后面成员要对齐到对齐数的整数倍的地址处,对齐数是编译器默认的对齐数(如果编译器有的话,VS是8)和成员数据类型的较小的一方

3.结构体总大小必须是最大对齐数(所有成员中对齐数最大的)的整数倍

4.如果结构体中嵌套了结构体,嵌套的结构体要对齐到自身成员的最大的对齐数的整数倍

假设现在有如下结构体,我们来求一下它的大小:

struct s
{
    char a;
    int i;
    char c;
};

具体过程如下:

1.3.2存在内存对齐的原因

1.平台原因

不是所有的平台都能够访问任意地址的任意数据的,某些平台如果访问了特定的数据是会出现异常的

2.性能原因

以32位机器访问上面的结构体为例,32位机器访问一次最多可访问4个字节

可以看到,机器可以正常访问到每个成员

现在假设成员之间没有空隙

中间的成员i的数据在读取时被分成了两部分,而为了正确读取出i的数据,处理器需要再次进入内存中进行访问,这样机器的效率就降低了

1.3.3默认对齐数的修改
#pragma pack(3) //设置默认对齐数为3,不填就是还原默认对齐数
 2.位段

位段和结构体类似,但有几点不同:

1.位段的成员为int、unsigned int或char,且成员数据类型必须相同

2.成员后面接一个冒号和一个数字

3.位段无法跨平台

位段的声明如下:

struct A
{
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
};
2.1位段的内存分配

位段内存分配规则如下:

1.位段中成员后的数字代表的是这个成员在内存中所占空间的大小,单位是bit,需要注意的是成员后面数字不能超过成员本身数据类型原本所占的空间大小(即int后面的数字不能超过32,char后面数字不能超过8)

2.位段空间的开辟是以4字节(int)或1字节(char)方式来开辟的

3.前面开辟出的空间前面的成员未占满,剩下的空间又不足以容纳下一个成员时,剩余空间舍弃,另外开辟新空间给下一个成员

以上述位段为例:

首先开辟4个字节的空间,容纳前3个成员,第四个成员再开辟另外的空间,所以大小为8

3.枚举 3.1枚举的定义

顾名思义就是一一列举,把可能的取值一一列举出来,比如十二生肖的十二种动物,一年的十二个月等

3.2枚举的声明

首先是关键字:enum

enum Day//一个星期的天数
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

枚举中的成员叫枚举常量

既然是常量,那么就会有值,在没有赋值的情况下,默认第一个成员的值为0,后面的成员的值依次+1,

枚举常量的赋值如下:

enum Day//一个星期的天数
{
    Mon=1,
    Tues=3,
    Wed=5,
    Thur=6,
    Fri=8,
    Sat=9,
    Sun=10
};
3.3枚举的大小

枚举中是所有可能会出现的值,在使用时枚举中的值不会同时出现,故在内存中不需要开辟所有的值的大小的空间

4.联合(共用体) 4.1联合定义

一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间

4.2联合的声明

关键字:union

union Un
{
    char c;
    int i;
};
4.3联合的大小

1.联合的大小不小于最大成员的大小
2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

所以上述枚举的大小为4

注:数组的对齐数为数组的元素的对齐数 

图中数组中的元素是char类型,对齐数为1,故最大对齐数为4,5不是4的整数倍,所以扩容到8

C语言的自定义类型就到这

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5713645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存