自定义类型:结构体,枚举,联合

目录

一  结构体:

        1.结构体类型的声明

        2.结构体的自引用

        3.结构体变量的定义和初始化

        4.结构体内存的对齐

        5.结构体传参

        6.结构体实现位段(位段填充&可移植性)

二 枚举:

        1.枚举类型的定义

        2.优点

        3.使用

三 联合:

        1.联合类型的定义

        2.特点

        3.大小的计算


一  结构体

        因为这个类型我更过博客啦,有些基础不详细说明(可以前翻~)

        1.声明:

struct tag
{
    member-list;
}variable-list;

        ~有一个很有趣的声明- 匿名(省略tag)

struct
{
	char i;
	int p;
	float b;
}x;
struct
{
	char i;
	int p;
	float b;
}*p;

        ~问题来了 p = &x; 可以吗?

                不行 -- 编译器会把上面的两个声明 当为两个完全不同的类型 是非法的

        2.自引用

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

        4.计算结构体大小

                i)  先掌握对齐规则:

                                            1    ~第一个成员在与结构体变量的偏移量为0的地址处

                                            2    ~其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处  (       对齐数=编译器默认的一个对齐数有的没有就是该成员大小)与该成员大小的较小值       )

                                            3    ~结构体总大小为最大对齐数的整数倍

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

哎反正你肯定看不懂 上图吧~

 啊 你还可以这样核实一下(别忘了引用头文件!!!)

 嵌套结构体版

 

                ii) 为什么存在内存对齐?

                        ~平台(移植)原因  ~性能原因

                        ~结构体的内存对齐是拿空间换的时间(可-占用空间小的尽量在一起 - 所用空间有所下降)

(可-占用空间小的尽量在一起 - 所用空间有所下降)对于这句话 上图

 

                iii)默认修改对齐数 #pragma pack()

        5.结构体传参

                ~传结构体地址

        6.位段

                i)什么是位段?

                        位段的声明与结构体是类似的 但有两个不同 ~位段成员必int,unsigned int,signed int (char也可)~位段成员名后有一个冒号和一个数字

struct A
{
	int _a : 2;  //a这个成员只占2bit
	int _b : 5;
	int _c : 10;
	int _d : 30;

};

                ii)位段的内存分配

                        空间需要 4  /  1 个字节开辟(int / char)--这也说明位段不跨平台

哎 肯定还是看不懂这文绉绉的字 上图!

 其实 还有一个特别好的栗子

 

                iii)跨平台问题

                        ~int 位段被当有符号数还是无符号数 不确定

                        ~最大数目不确定(16位平台 sizeof(int)-2字节 -16bit ---这可以看出那上面的代码d 30 就有点问题了)

                        ~位段成员在内存中 以从左向右 还是从右向左 分配 不确定

                        ~如果一个结构包含两个位段 第二个位段成员比较大 无法容纳在第一个位段余位时 是否还用剩余余位 不确定

二 枚举

        1.枚举的类型定义

enum Sex
{
	MALE,
	FEMALE,
	SECRET
};



int main()
{
	enum Sex s = MALE;
	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);

	return 0;
}

                ~这些都是有值的 默认从0开始 一次递增1 当然在定义的时候 可以赋给初始值

         2.特点

                ~增加代码的可读性+可维护性

                ~和 #define 定义的标识符 比 枚举 有类型检查 会更严谨

                ~防止命名污染(封装)

                ~便于调试

                ~使用方便 一次可 多个常量

三 联合

        1.一种特殊的自定义类型 也包含一系列成员

           特征:这些成员共用一块空间(所以 ~同一时间用一个量c或i  ~改i 就会改c  ~成员的起始位置同 )

union Un
{
	char c;
	int i;
};

你肯定也看不懂上个图图~

 

        2.特点

                ~共用一块空间(一个联合变量大小,至少为最大成员大小)

                可以利用这个特点写一个代码--判断大小端

int check_sys()
{
	union Un
	{
		char c;
		int i;
	}u;
	u.i = 1;
	return u.c;
}
int main()
{
	if (1 == check_sys())
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

        3.大小计算

                ~联合的大小至少是最大成员的大小

                ~当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍
莫名想上传一下我的笔记 可以浅浅康康一下~~~

 

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值