关于位段+枚举+联合(共用体)的一些笔记

位段

什么是位段

1.位段的成员必须是int、unsigned int 或signed int 或者是char。
2.位段的成员名后边有一个冒号和一个数字。

#include<stdio.h>
struct A
{
	int a: 2;
	int b: 5;
	int c: 10;
	int d: 30;
}a;
int main()
{
	printf("%d\n",sizeof(a));
	return 0;
}//编译结果:8

 

位段的内存分配

1. 位段的成员可以是int unsigned int signed int 或者是char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

#include<stdio.h>
struct A
{
	char a: 3;
	char b: 4;
	char c: 5;
	char d: 6;

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

 

位段的跨平台问题

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

 

总结

跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

枚举

#include<stdio.h>
enum color//枚举类型
{
	red=0,//可以进行赋初值
	green,//枚举常量
	blue
};
int main()
{
	enum color a=2;//不能这样复制,两边类型不一样
	enum color clr = red;
	printf("%d %d %d\n",red,green,blue);//编译结果:1 2 3
}

枚举大小的计算

#include<stdio.h>
enum color 
{
	red,
	green,
	blue
}clr;
int main()
{
	clr =red;
	printf("%d\n",sizeof(clr));
	return 0;
}//编译结果:4

枚举优点

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

联合(共用体)

特征:公用一块空间

#include<stdio.h>
union un
{
	int a;
	char b;
}un;
int main()
{
	un.b=0x55;
	un.a=0x11223344;
	printf("%d\n",sizeof(un));
	printf("%p\n",&(un));
	printf("%p\n",&(un.a));
	printf("%p\n",&(un.b));
	printf("%x\n",un.a);
	printf("%x\n",un.b);
	return 0;
}
//编译结果:
//4
//0090715C
//0090715C
//0090715C
//0x11223344
//0x44

联合体中只能用其中一个里面的变量。两个一起用会出现问题

判断计算机大端存储还是小端存储

第一种:

#include<stdio.h>
int main()
{
	int a=1;
	int ret=*((char*)&a);
	if(1==ret)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

第二种:

#include<stdio.h>
int check_sys(int* a)
{
	return *(char*)a;
}
int main()
{
	int a=1;
	int ret=check_sys(&a);
	if(1==ret)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

第三种:(使用联合体)

#include<stdio.h>
int check_sys(int* a)
{
	union un
	{
		char a;
		int b;
	}u;
	u.b=1;
	return u.a;
}
int main()
{
	int a=1;
	int ret=check_sys(&a);
	if(1==ret)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

以上三种编译结果都为:小端存储

联合大小的计算

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

#include<stdio.h>
union um1
{
	char arr[7];
	int a;
}u1;
union um2
{
	short arr[7];
	int a;
}u2;
int main()
{
	printf("%d\n",sizeof(u1));
	printf("%d\n",sizeof(u2));
}//编译结果:8 16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值