栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

自定义类型
  • 一、结构体
    • 1.1 结构体的声明
    • 1.2 结构体的自引用
    • 1.3 结构体变量的初始化
    • 1.4 结构体的内存对齐和大小计算
    • 1.5 为什么存在内存对齐❗️❗️
  • 二、位段
    • 2.1 位段的概念
    • 2.2 位段的大小计算
    • 2.3 位段的内存分配
    • 2.4 位段的跨平台问题
  • 三、枚举
    • 3.1 枚举类型的定义
    • 3.2 枚举的优点
    • 3.3 枚举的使用
  • 四、联合体(共用体)
    • 4.1 联合体的定义
    • 4.2 联合体的特点
    • 4.3 联合体的大小计算

一、结构体 1.1 结构体的声明

用通讯录的例子展示:

struct PeoInfo
{
	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;

int main()
{
	p = &x;
	return 0;
}

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


1.2 结构体的自引用
struct Node
{
	int data;
	struct Node next;
};

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

struct Node
{
	int data;
	struct Node* next;
};

1.3 结构体变量的初始化
struct Node
{
	int data;
	struct Node* next;
}n1;
struct Node n2;

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

struct A
{
	int a;
	int b;
};

struct B
{
	int c;
	struct A a;
};

int main()
{
	struct A a = { 1, 2 };
	struct B b = { 1, {1, 1} };
	return 0;
}
1.4 结构体的内存对齐和大小计算

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


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

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


假设在32位机器(一次访问四个字节)访问a:

总体来说:
结构体内存对齐是拿空间换时间的做法。

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


二、位段 2.1 位段的概念
struct A
{
	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表示它只需要两个比特位。所以后边的数字不能超过他自己类型的范围
计算方法:

要注意没用完的空间被浪费了

struct A
{
	int a : 1;
	char b;
};

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


2.3 位段的内存分配
struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S 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 枚举类型的定义
enum Day//星期
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};

像星期,颜色这种有限的东西可以用枚举。
enum Day是枚举类型{}内叫枚举常量。


3.2 枚举的优点

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


3.3 枚举的使用
enum Day//星期
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};

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

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

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


四、联合体(共用体) 4.1 联合体的定义
//联合类型的声明
union Un
{
	char c;
	int i;
};

4.2 联合体的特点

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


4.3 联合体的大小计算

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



暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014979.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号