位段、枚举和联合体

位段

什么是位段:

位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 int、unsigned int 或signed int
2.位段的成员名后边有一个冒号和一个数字

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

int main()
{
	printf("%d\n", sizeof(struct S));//8
	return 0;
}

这里:后跟的数字不再表示所占字节了,而表示的是所占比特位

int开辟4个字节,出现32个比特位。a占用2个,b占用5个,c占用10个,还剩余15个。这时不够d使用。所以d需要重新开辟4个字节,32个比特位,占用30个,还剩余2个。共使用8个字节。
在这里插入图片描述

位段的内存分配
  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
struct S
{
	char a : 3;
	char b : 4;
	char c : 5;
	char 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位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

枚举

enum Sex
{
	MALE=1,
    FEMALE=2,
    SECRET=4
};

int main()
{
	printf("%d\n",MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);
	return 0;
}
枚举的优点
  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量
void menu()
{
	printf("********************\n");
	printf("***1.add     2.sub***\n");
	printf("***3.mul     4.div***\n");
	printf("***0.exit***\n");
	printf("********************\n");
}

enum Option
{
	EXIT,
    ADD,
    SUB,
    MUL,
    DIV,
};

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			break;
		case  ADD:
			break;
		case SUB:
			break;
		case DIV:
			break;
		case MUL:
			break;
		default:
			break;
		}
	} while ();
		return 0;
}

联合体

1.联合体的定义:
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)

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

int main()
{
    //联合变量的定义
	union Un u;
	printf("%p\n", &u);//003CFA68
	printf("%p\n", &(u.c));//003CFA68
	printf("%p\n", &(u.i));//003CFA68
	printf("%p\n", &(u.d));//003CFA68
	//计算连个变量的大小
	printf("%p\n", sizeof(u));//8
	return 0;
}

2.联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
在这里插入图片描述
3.判断计算机的大小端存储

//0x 00 00 00 01
//低           高
//小端:01 00 00 00
//大端:00 00 00 01

//int check_sys()
//{
//	int a = 1;
//	return *(char*)&a;
//}
//使用联合体
int check_sys()
{
	union Un
	{
		char c;
		int i;
	}u;
	u.i = 1;
	//返回1,表示小端
	//返回0,表示大端
	return u.c;
}

int main()
{
	//对char*解引用访问一个字节
	//if (*(char*)&a == 1)
	if(check_sys()==1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

4.联合大小的计算
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

union Un1
{
	char c[5];//5
	int i;//4
};

union Un2
{
    short c[7];//14
    int i;//4
};

int main()
{
	printf("%d\n", sizeof(union Un1));//8
	printf("%d\n", sizeof(union Un2));//16
	return 0;
	
}
发布了37 篇原创文章 · 获赞 3 · 访问量 1090

猜你喜欢

转载自blog.csdn.net/weixin_43264873/article/details/103057284