山东闪电建站网,dw手机销售网站制作,seo实训报告,电梯企业网站制作#x1f435;本篇文章将会对位段、枚举和联合的相关知识进行讲解 1. 位段#x1f4da;
1.1 什么是位段
位段的声明和结构体类似#xff0c;但是有两点不同#xff1a; 1.位段的成员必须是int#xff0c;unsigned int#xff0c;signed int (C99之后也可以是其他成员本篇文章将会对位段、枚举和联合的相关知识进行讲解 1. 位段
1.1 什么是位段
位段的声明和结构体类似但是有两点不同 1.位段的成员必须是intunsigned intsigned int (C99之后也可以是其他成员但一般是int, char) 2.位段的成员的后面都有一个冒号和一个数字代表该成员所占的比特位 假如A是一个普通的结构体那么此时A的大小为16个字节那么位段A的大小是多少
struct A
{int a : 2;int b : 5;int c : 10;int d : 30;
};
printf(%zd\n, sizeof(struct A));得到的结果为8可以看出位段相比于结构体更能节省空间那位段是怎么分配内存空间的为什么A的大小是8个字节 1.2 位段的内存分配
位段在空间上按照4个字节int或一个字节char为单位来开辟的也就是当位段成员主要是int时它会先开辟4个字节当不够用时会再开辟4个字节当位段成员主要是char时它会先开辟1个字节当不够用时会再开辟1个字节
除此之外位段还有许多跨平台问题
1. int位段究竟是无符号unsigned int还是有符号signed int是不确定的
2. int位段的最大位段数是不确定的因为在16位机器上int占2个字节在32位机器上int占4个字节
3. 位段成员在内存中是从左到右分配还是从右到左分配是不确定的比如还是以上题为例由于位段成员主要是int类型所以位段在空间上按4个字节为单位来开辟的先开辟4个字节 4. 当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余的位还是利用这是不确定的
比如char位段先开辟一个字节a占6个比特位b占4个比特位 下面以一个例题为例
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;
} 2. 枚举
枚举就是一一列举
2.1 枚举的定义
enum Color
{RED,GREEN,BLUE
};每一个枚举常量都有对应的值第一个枚举常量的默认值为0之后依次递增1在上述代码中枚举常量RED的值为0GREEN为1BLUE为2
enum Color
{RED,GREEN,BLUE
};int main()
{printf(%d, RED); //打印结果为0return 0;
}
我们也可以修改默认值
enum Color
{RED 3,GREEN,BLUE
};这样RED的值就变成了3GREEN和BLUE也依次变为4和5 2.1 枚举的使用
enum Color
{RED,GREEN 5,BLUE
};int main()
{enum Color clr GREEN;//给枚举类型的变量赋值时要用枚举常量clr 6; //这种形式的代码在vs的.c文件中不会报错这是因为vs的.c文件对类型检查不够严格当把.c文件改为.cpp文件时程序就会报错所以不建议这样写代码return 0;
} 3. 联合
3.1 联合的定义
联合体共用体也是一种自定义类型它也包含一系列的成员它的特征是这些成员共用同一空间
union un
{char c;int i;
};int main()
{union un u; //创建联合体变量printf(%p\n, u); //求变量的地址printf(%p\n, u.c); printf(%p\n, u.i); //求成员的地址return 0;
}有打印结果可以看出联合体的内部成员共用同一块空间 在深度剖析数据在内存中的存储中讲解过大小端存储模式当时写过判断大小端存储模式的代码 int check_sys()
{int a 1;return *(char*)a; //判断该数据的第一个字节是多少
}int main()
{int ret check_sys();if (ret 1){printf(小端存储\n);}else{printf(大端存储\n);}return 0;
}同样我们也可以用联合实现判断大小端的功能
int check_sys()
{union un{char c;int i;}u;u.i 1;return u.c;
}3.2 计算联合的大小
联合体的成员共用同一块内存空间一个联合体变量的大小至少是其最大成员的大小因为当最大成员的大小不是最大对齐数的整数倍时就要对齐到最大对齐数的整数倍处
union un
{char c[5];int i;
}u;int main()
{printf(%zd, sizeof(u)); //结果为8return 0;
}
上述代码中c的对齐数是1i的对齐数是4所以最大对齐数是4而char c[5]的大小是5个字节所以要再浪费3个字节对齐到4的倍数也就是8个字节 至此有关结构体、位段、枚举和联合的知识全部讲解完毕之后会讲解动态内存管理