位段
什么是位段
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