IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C】自定义数据类型 -> 正文阅读

[C++知识库]【C】自定义数据类型

目录

一、结构体

????????结构体声明

????????特殊声明

????????结构体创建变量

????????结构体自引用

????????结构体重定义

????????结构体变量初始化

????????结构体内存对齐

????????offsetof

????????修改最大对齐数

????????结构体传参

二、位段

????????位段的内存分配

????????位段的跨平台问题

????????位段的应用

三、联合

????????联合内成员的空间占用

????????联合的大小计算

四、枚举

????????枚举内成员值

????????枚举的使用

????????枚举相对于?define 的优点


一、结构体

结构体:由变量组成的数据类型。

????????结构体声明

//创建「人」的数据类型
struct People //「struct People」为数据类型名,其中「struct」固定,「People」自定义
{
	char name[10];//姓名
	int age;//年龄
};

????????特殊声明(不加结构体标签)

struct
{
	char name[10];
	int age;
};

当用特殊声明创建多个结构体时,编译器将全部视为不同类型。

例:用特殊声明创建 2 个一样的结构体,创建变量后进行赋值。

????????结构体创建变量

??(1)主函数内创建变量(局部变量)

struct People p1, p2;
struct People* p1, *p2;//指针变量

(2)声明结构体时创建变量(全局变量)

struct People
{
	char name[10];
	int age;
}p1,p2;//创建「p1」「p2」两个「struct People」类型的变量
struct People
{
	char name[10];
	int age;
}*p1,*p2;//创建「p1」「p2」两个「struct People」类型的指针变量

????????结构体自引用

错误:

struct People
{
	char name[10];
	int age;
	struct People p;
};

当 People?中创建了 p?时,p?里面还会包含一个 p,不断循环下去,导致计算不出占用内存大小,所以编译器报错。

正确:

struct People
{
	char name[10];
	int age;
	struct People *p;
};

当用指针的方式进行自引用,只需提供一个固定的指针类型大小就可以了。

特殊声明不可进行自引用

?

?将?struct?进行重定义之后,编译器还是会将创建出来的不同变量视为不同类型。

????????结构体重定义

typedef struct People
{
    char name[10];
    int age;
}P;
//将「struct People」重定义为「P」

????????结构体变量初始化

?(1)一般初始化

struct People
{
	char name[10];
	int age;
};

struct People p = { "张三",18 };

struct People
{
	char name[10];
	int age;
}p = { "张三",18 };

(2)嵌套初始化

struct A
{
	int b;
};

struct People
{
	char name[10];
	int age;
	struct A a;
};

struct People p = { "张三",18 ,{0} };
//因为p中的a是结构体,所以也需要使用{}

????????结构体内存对齐

?用空间换取时间

作用:

(1)提高可移植性,某些平台只能在特定地址取出特定数据类型。

(2)提高性能:有时访问未对齐内存可能要比对齐内存多访问一次,因为内存对齐后,系统就知道从哪开始访问获取该数据。

?内存对齐规则:

(1)所有成员须对其到对齐数的整数倍偏移量处

(2)结构体总大小为成员最大对齐数的整数倍

(3)数组或嵌套结构体的偏移量为自身内变量的最大偏移量

对齐数:该成员占用字节数,VS?下最大不超过8

偏移量:内存单位与起始位置的距离

集中占用空间小的成员可以节约空间

例 1:

struct X
{
	char c1;
	int i;
	char c2;
}x;

struct Y
{
	char c1;
	char c2;
	int i;
}y;

int main()
{
	sizeof(x);
	sizeof(y);

	return 0;
}

答案:12、8

??例 2:

struct X
{
	char c1;
	int i;
	char c2;
};

struct Y
{
	char c1;
	char c2;
	struct X x;
    char c3;
}y;

int main()
{
	sizeof(y);

	return 0;
}

答案:20

????????offsetof

?使用?offsetof?可查看结构体类型中变量所在偏移处,需包含头文件?< stddef.h>

例:

struct X
{
	char c1;
	int i;
	char c2;
}x;

struct Y
{
	char c1;
	char c2;
	struct X x;
	char c3;
}y;

int main()
{
	printf("%d\n", sizeof(y));
	printf("%d\n", offsetof(struct Y, c1));
	printf("%d\n", offsetof(struct Y, c2));
	printf("%d\n", offsetof(struct Y, x));
	printf("%d\n", offsetof(struct Y, c3));

	return 0;
}

????????修改最大对齐数

?例:

#pragma pack(1)//将最大对齐数改为1
struct X
{
	char c1;
	int i;
	char c2;
}x;
#pragma pack()//将最大对齐数改回默认值

????????结构体传参

(1)值传递

struct A
{
	int i;
};

void print(struct A a)
{
	printf("%d", a.i);
}

int main()
{
	struct A a = { 1 };
	print(a);

	return 0;
}

(2)地址传递

struct A
{
	int i;
};

void print(struct A* a)
{
	printf("%d", a->i);
}

int main()
{
    struct A a = { 1 };
	print(&a);

	return 0;
}

函数传参时需要进行压栈,如果参数过大会导致不必要的时间、空间消耗,所以结构体传参时,地址传递优于值传递。

二、位段

声明结构体时,在其中的成员后加上为该成员分配的内存(以位为单位),该结构体成员称为位段。

?例:

struct S
{
	int a : 3;//给a分配3个比特位
	int b : 4;//给b分配4个比特位
	int c : 5;//给c分配5个比特位
	int d : 4;//给d分配4个比特位
};

????????位段的内存分配

?(1)位段只能是整型

(2)位段以不同整型大小按需开辟空间

例:

struct S
{
	int a : 3;
	int b : 4;
	int c : 5;
	int d : 4;
};

int main()
{
	struct S s = { 0 };
	s.a = 10;
	s.b = 12;
	s.c = 3;
	s.d = 4;

	return 0;
}

????????位段的跨平台问题

位段不可跨平台

(1)int?类型被当做有符号或无符号不确定

(2)位数不确定(16?为机器下?int?为 2?字节)

(3)内存从左向右分配或相反,尚未确定

(4)开辟新空间时,旧空间利用或舍弃未确定

????????位段的应用

位段应用在数据报文中,因为报文中每个字段所需空间极小。

三、联合

所有成员共用同一片空间的数据类型叫联合。

联合的声明、变量创建同结构体一样,只需将结构体中的「struct」替换为「union」

????????联合内成员的空间占用

?例:

union U
{
	int i;
	char c;
}u;


int main()
{
	printf("%d\n", &(u.i));
	printf("%d\n", &(u.c));//(1)
	
	u.i = 0x11223344;
	u.c = 0x55;
	printf("%x\n", u.i);//(2)(小端环境下)

	return 0;
}

结果:

(1)2 个地址相同

(2)44332200

????????联合的大小计算

联合的大小为最大成员大小且为成员内最大对齐数的倍数

例 1:

union U
{
	char c[5];
	int i;
}u;
int main()
{
	printf("%d\n", sizeof(u));
	return 0;
}

答案:8

最大成员大小为 5(char [5]),最大对齐数为 4(int)

例 2:

union U
{
	short c[7];
	int i;
}u;
int main()
{
	printf("%d\n", sizeof(u));
	return 0;
}

答案:16

最大成员大小为 5(short [7]),最大对齐数为 4(int)

四、枚举

?枚举的作用类似?define,但是枚举将定义的常量有类型且以类型分组。

例:

enum Colour//颜色
{
	BLUE,
	GREEN,
	RED
};

enum Sex//性别
{
	MAN,
	WOMAN
};

????????枚举内成员值

枚举内成员的值默认从 0?开始递增,可自定义。

例 1:

enum Colour
{
	BLUE,
	GREEN,
	RED
};

int main()
{
	printf("%d", BLUE);
	printf("%d", GREEN);
	printf("%d", RED);
	return 0;
}

结果:0、1、2

例 2:

enum Colour
{
	BLUE=1,
	GREEN,
	RED=5
};

int main()
{
	printf("%d", BLUE);
	printf("%d", GREEN);
	printf("%d", RED);
	return 0;
}

结果:1、2、5

????????枚举的使用

例:

enum Colour
{
	BLUE=,
	GREEN,
	RED=
};

int main()
{
	enum Colour c;
	c = GREEN;
	return 0;
}

错误用法:

enum Colour
{
	BLUE,
	GREEN,
	RED
};

int main()
{
	enum Colour c;
	c = 1;
	return 0;
}

因为 1?是整型,而 c?是?enum Colour?类型,不同类型不能进行赋值。

????????枚举相对于?define 的优点

(1)可一次性定义多个常量

(2)有类型,更严谨

(3)便于调试,程序执行前的预编译会进行宏替换,从而不能观察到?define?定义的值

(4)增加代码可读性

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:02:42  更:2022-07-17 16:06:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:31:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码