当前位置:   article > 正文

C语言:结构体、联合体和枚举(3)

C语言:结构体、联合体和枚举(3)

一.联合体

1.联合体类型的声明:

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体叫:共用体
给联合体其中⼀个成员赋值,其他成员的值也跟着变化


2.联合体(共用体)的大小
代码1:
  1. union Un
  2. {
  3. char c;//1
  4. int i;//4
  5. };
  6. int main()
  7. {
  8. union Un u = { 0 };
  9. //计算联合体大小
  10. printf("%zd\n", sizeof(u));
  11. return 0;
  12. }

 

代码2: 
  1. //联合体类型的声明
  2. union Un
  3. {
  4. char c;//1
  5. int i;//4
  6. };
  7. int main()
  8. {
  9. union Un u = { 0 };
  10. //计算联合体大小
  11. printf("%zd\n", sizeof(u));
  12. printf("%p\n", &u);
  13. printf("%p\n", &(u.c));
  14. printf("%p\n", &(u.i));
  15. return 0;
  16. }

通过 代码2及其运行结果我们可以看到联合体的地址及其成员的地址一样,这说明联合体u和联合体成员c,i 指向同一块内存空间,共用同一块空间。如下图:

3.联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

代码3:

  1. union Un
  2. {
  3. char c;
  4. int i;
  5. };
  6. int main()
  7. {
  8. union Un u = { 0 };
  9. u.i = 0x44332211;
  10. u.c = 0x55;
  11. return 0;
  12. }


 

 

 

解析:由于联合体成员共用同一块内存空间,指向同一块内存空间,所以 改变其中任意一个成员的大小都会影响其他成员的大小,当我们为成员i赋值为 0x44332211时,联合体的内容就为0x44332211,当我们为成员c赋值为0x55时,联合体的低地址处的内容44就会被修改为55,因此我们建议读者在使用联合体时应该注意尽量不要同时使用联合体成员。

 4.相同成员的结构体和联合体对比
  1. struct S
  2. {
  3. char c;
  4. int i;
  5. };
  6. union U
  7. {
  8. char c;
  9. int i;
  10. };
  11. int main()
  12. {
  13. struct S s = { 0 };
  14. union U u = { 0 };
  15. printf("%zd\n", sizeof(s));
  16. printf("%zd\n", sizeof(u));
  17. return 0;
  18. }

 

 

 

 

 

5.联合体大小的计算

1).联合的大小至少是最大成员的大小

2).当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

  1. union Un1
  2. {
  3. char c[5];//1 8 1
  4. int i; //4 8 4
  5. };
  6. union Un2
  7. {
  8. short c[7];//2 8 2
  9. int i; //4 8 4
  10. };
  11. int main()
  12. {
  13. printf("%zd\n", sizeof(union Un1));
  14. printf("%zd\n", sizeof(union Un2));
  15. return 0;
  16. }

解析:由于联合体的大小至少是最大成员的大小,在union Un1中成员c占用内存空间5个字节,vs默认对齐数为8.所以c的对齐数为1;成员i的大小为4个字节,vs默认对齐数为8.所以i的对齐数为4,所以5个字节的大小不是联合体的最大对齐数4的整数倍,所以需要继续浪费3个字节的内存空间,因此联合体共占用8个字节大小的内存空间,联合体的大小为8。


 在union Un2中,成员s占用内存空间 14(2 * 7 = 14)个字节,vs默认对齐数为8.所以c的对齐数为2;成员i的大小为4个字节,vs默认对齐数为8.所以i的对齐数为4,所以14个字节的大小不是联合体的最大对齐数4的整数倍,所以需要继续浪费2个字节的内存空间,因此联合体共占用16个字节大小的内存空间,联合体的大小为16。

二:枚举

1.枚举类型的定义


 枚举顾名思义就是一一列举。
把可能的取值一一列举。
比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举
月份有12个月,也可以一一列举
三原色,也是可以一一列举
这些数据的表式就可以使用枚举

  1. enum Day//星期
  2. {
  3. Mon,
  4. Tues,
  5. Wed,
  6. Thur,
  7. Fri,
  8. Sat,
  9. Sun
  10. };
  11. enum Color//颜⾊
  12. {
  13. RED,
  14. GREEN,
  15. BLUE
  16. };

以上定义的 enum Day , enum Color 都是枚举类型。
{}中的内容是枚举类型的可能取值,也叫 枚举常量 。
这些可能取值都是有值的,如果变量不初始化默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

代码4:
  1. enum Color//颜⾊
  2. {
  3. RED ,
  4. GREEN ,
  5. BLUE
  6. };
  7. int main()
  8. {
  9. printf("%d\n", RED);
  10. printf("%d\n", GREEN);
  11. printf("%d\n", BLUE);
  12. return 0;
  13. }


 

代码5: 
  1. enum Color//颜⾊
  2. {
  3. RED,
  4. GREEN = 3,
  5. BLUE
  6. };
  7. int main()
  8. {
  9. printf("%d\n", RED);
  10. printf("%d\n", GREEN);
  11. printf("%d\n", BLUE);
  12. return 0;
  13. }

 

 代码6:
  1. enum Color//颜⾊
  2. {
  3. RED = 6,
  4. GREEN = 3,
  5. BLUE
  6. };
  7. int main()
  8. {
  9. printf("%d\n", RED);
  10. printf("%d\n", GREEN);
  11. printf("%d\n", BLUE);
  12. return 0;
  13. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/705685
推荐阅读
相关标签
  

闽ICP备14008679号