位字段

作者:追风剑情 发布于:2020-4-10 15:46 分类:C

示例:位字段

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. //提供CHAR_BIT的定义,CHAR_BIT表示每字节的位数
  6. #include <limits.h>
  7. //C99定义了bool、true、false
  8. #include <stdbool.h>
  9.  
  10. /////////////////////////////////////////////////////////////////////////////////////////////
  11. /*
  12. 位字段:
  13. 操控位的第2种方法是位字段(bit field)。位字段是一个signed int或unsigned int类型变量中
  14. 的一组相邻的位(C99或C11新增了_Bool类型的位字段)。位字段通过一个结构声明来建立,该结构声明
  15. 为每个字段提供标签,并确定该字段的宽度。
  16. */
  17.  
  18. //下面的声明建立了一个4个1位的字段
  19. struct {
  20. unsigned int autfd : 1;
  21. unsigned int bldfc : 1;
  22. unsigned int undln : 1;
  23. unsigned int itals : 1;
  24. } prnt; //变量prnt被储存在int大小的内存单元中,但是在本例中只使用了其中的4位
  25.  
  26. //下面创建了两个2位的字段和一个8位的字段
  27. struct {
  28. unsigned int code1 : 2;
  29. unsigned int code2 : 2;
  30. unsigned int code3 : 8;
  31. } prcode;
  32.  
  33. /*
  34. 如果声明的总数超过了一个unsigned int类型的大小,则会用到下一个unsigned int类型的存储位置。
  35. 一个字段不允许跨越两个unsigned int之间的边界。编译器会自动移动跨界的字段,保持unsigned int
  36. 的边界对齐。一旦发生这种情况,第1个unsigned int中会留下一个未命名的“洞”。
  37. 可以用未命名的字段宽度“填充”未命名的“洞”。使用一个宽度为0的未命名字段迫使下一个字段与下一
  38. 个整数对齐:
  39. */
  40. struct {
  41. unsigned int field1 : 1;
  42. //field1与field2之间,有一个2位的空隙
  43. unsigned int : 2;
  44. unsigned int field2 : 1;
  45. unsigned int : 0; //迫使下一个字段与下一个整数对齐
  46. //field3将储存在下一个unsigned int中
  47. unsigned int field3 : 1;
  48. } stuff;
  49.  
  50. /*
  51. 字段储存在一个int中的顺序取决于机器。在有些机器上,存储的顺序是从左往右,而在另一些机器
  52. 上,是从右往左。另外,不同的机器中两个字段边界的位置也有区别。由于这些原因,位字段通常都不容易
  53. 移植。尽管如此,有些情况却要用到这种不可移植的特性。
  54. */
  55. ////////////////////////////////////////////////////////////////////////////////////////////////////
  56.  
  57. /* 线的样式 */
  58. #define SOLID 0 //实线
  59. #define DOTTED 1 //点线
  60. #define DASHED 2 //虚线
  61.  
  62. /* 三原色 */
  63. #define BLUE 4
  64. #define GREEN 2
  65. #define RED 1
  66. /* 混合色 */
  67. #define BLACK 0
  68. #define YELLOW (RED | GREEN)
  69. #define MAGENTA (RED | BLUE)
  70. #define CYAN (GREEN | BLUE)
  71. #define WHITE (RED | GREEN | BLUE)
  72.  
  73. const char * colors[8] = {"black", "red", "green", "yellow","blue", "magenta", "cyan", "white"};
  74.  
  75. //声明一个描述方框属性的结构体
  76. struct box_props {
  77. bool opaque : 1; //是否透明; 或者 unsigned int (C99以前)
  78. unsigned int fill_color : 3;//填充色
  79. unsigned int : 4;
  80. bool show_border : 1;//是否显示边框; 或者 unsigned int (C99以前)
  81. unsigned int border_color : 3; //边框颜色
  82. unsigned int border_style : 2; //边框样式
  83. unsigned int : 2;
  84. };
  85.  
  86. void show_settings(const struct box_props * pb);
  87.  
  88. int main(int argc, char* argv[])
  89. {
  90. //由于每个字段恰好为1位,所以只能为其赋值1或0
  91. prnt.itals = 0;
  92. prnt.undln = 1;
  93.  
  94. //要确保所赋的值不超出字段可容纳的范围
  95. prcode.code1 = 0;
  96. prcode.code2 = 3;
  97. prcode.code3 = 102;
  98.  
  99. /* 创建并初始化box_props结构 */
  100. struct box_props box = { true, YELLOW, true, GREEN, DASHED };
  101.  
  102. printf("Original box settings:\n");
  103. show_settings(&box);
  104.  
  105. box.opaque = false;
  106. box.fill_color = WHITE;
  107. box.border_color = MAGENTA;
  108. box.border_style = SOLID;
  109. printf("\nModified box settings:\n");
  110. show_settings(&box);
  111.  
  112. system("pause");
  113. return 0;
  114. }
  115.  
  116. void show_settings(const struct box_props * pb)
  117. {
  118. printf("Box is %s.\n",
  119. pb->opaque == true ? "opaque" : "transparent");
  120. printf("The fill color is %s.\n", colors[pb->fill_color]);
  121. printf("Border %s.\n",
  122. pb->show_border == true ? "shown" : "not shown");
  123. printf("The border color is %s.\n", colors[pb->border_color]);
  124. printf("The border style is ");
  125. switch (pb->border_style)
  126. {
  127. case SOLID: printf("solid.\n"); break;
  128. case DOTTED: printf("dotted.\n"); break;
  129. case DASHED: printf("dashed.\n"); break;
  130. default: printf("unknown type.\n");
  131. }
  132. }

运行测试

1111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号