0


【C语言】自定义类型总结

自定义类型

一、结构体

1.1 结构体的声明

用通讯录的例子展示:

structPeoInfo{char name[10];//姓名int age;//年龄char sex[6];//性别char tel[13];//电话char addr[20];//地址}p1;//p1是全局变量

这是普通的声明,而还有另一种声明的方式:匿名结构体的声明。

struct{char name[10];//姓名int age;//年龄char sex[6];//性别char tel[13];//电话char addr[20];//地址}p1;//p1是全局变量

匿名结构体只能在声明的后边创建变量,其他地方不能用。

struct{int a;char b;float c;}x;struct{int a;char b;float c;}a[20],* p;intmain(){
    p =&x;return0;}

要注意这种代码是不合法的,编译器会默认把上面两个类型当成不同的类型。


1.2 结构体的自引用

structNode{int data;structNode next;};

有人可能会这么写。但是这样会出现问题:无法计算Node的大小。所以正确用法:

structNode{int data;structNode* next;};

1.3 结构体变量的初始化

structNode{int data;structNode* next;}n1;structNode n2;

两种定义方法都可以。
初始化要使用{},含有嵌套的就在{}里加{}。

structA{int a;int b;};structB{int c;structA a;};intmain(){structA a ={1,2};structB b ={1,{1,1}};return0;}

1.4 结构体的内存对齐和大小计算

里面有详细介绍和练习:
结构体/联合体大小的计算


1.5 为什么存在内存对齐❗️❗️

1️⃣平台原因
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2️⃣性能原因
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

在这里插入图片描述
假设在32位机器(一次访问四个字节)访问a:
在这里插入图片描述
总体来说:
结构体内存对齐是拿空间换时间的做法。

所以为了节省空间,我们在设计时要:让占用空间小的成员尽量集中在一起。


二、位段

2.1 位段的概念

structA{int _a :2;int _b :5;int _c :10;int _d :30;};

可以看出他跟结构体的区别有两点:

1)位段的成员必须是 int、unsigned int 或signed int (也可以是char类型)。
2)位段的成员名后边有一个冒号和一个数字。


2.2 位段的大小计算

首先要知道冒号后面的数字是什么意思:
int的大小是4个字节,后边的2表示它只需要两个比特位。所以后边的数字不能超过他自己类型的范围。
计算方法:
在这里插入图片描述
要注意没用完的空间被浪费了

structA{int a :1;char b;};

这个位段的大小也为8,因为要考虑内存对齐而且不同的数据类型不能用一块空间。


2.3 位段的内存分配

structS{char a:3;char b:4;char c:5;char d:4;};structS s ={0};
s.a =10;
s.b =12;
s.c =3;
s.d =4;

在这里插入图片描述


2.4 位段的跨平台问题

1) int 位段被当成有符号数还是无符号数是不确定的。
2) 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题)。
3) 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4) 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。


三、枚举

3.1 枚举类型的定义

enumDay//星期{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

像星期,颜色这种有限的东西可以用枚举。

enum Day

是枚举类型{}内叫枚举常量。


3.2 枚举的优点

1) 增加代码的可读性和可维护性
2) 和#define定义的标识符比较枚举有类型检查,更加严谨。
3) 防止了命名污染(封装)
4) 便于调试
5) 使用方便,一次可以定义多个常量


3.3 枚举的使用

enumDay//星期{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

其实这些枚举常量都有值,从0开始,往后+1。也可以自己赋值:

enumDay//星期{
    Mon =1,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

这样就是从1往后加。后面可以直接用枚举变量来赋值


四、联合体(共用体)

4.1 联合体的定义

//联合类型的声明union Un
{char c;int i;};

4.2 联合体的特点

因为联合体是共用一块空间,所以改变其中一个变量另一个变量也会改变。


4.3 联合体的大小计算

里面有详细介绍和练习:
结构体/联合体大小的计算




本文转载自: https://blog.csdn.net/qq_66314292/article/details/125784159
版权归原作者 命由己造~ 所有, 如有侵权,请联系我们删除。

“【C语言】自定义类型总结”的评论:

还没有评论