1 /*-----------------------------------
2 dualview.c -- 位字段和按位运算符
3 -----------------------------------*/
4
5 #include <stdio.h>
6 #include <limits.h>
7
8 //边框线样式
9 #define SOLID 0
10 #define DOTTED 1
11 #define DASHED 2
12
13 //三原色
14 #define BLUE 4
15 #define GREEN 2
16 #define RED 1
17
18 //混合颜色
19 #define BLACK (RED & GREEN & BLUE)
20 #define YELLOW (RED | GREEN)
21 #define MAGENTA (RED | BLUE)
22 #define CYAN (GREEN | BLUE)
23 #define WHITE (RED | BLUE | GREEN)
24
25 //按位方法中用到的符号常量
26 #define OPAQUE 0x1
27 #define FILL_BLUE 0x8
28 #define FILL_GREEN 0x4
29 #define FILL_RED 0x2
30 #define FILL_MASK 0xE //掩码
31 #define BORDER 0x100
32 #define BORDER_BLUE 0x800
33 #define BORDER_GREEN 0x400
34 #define BORDER_RED 0x200
35 #define BORDER_MASK 0xE00
36 #define B_SOLID 0
37 #define B_DOTTED 0x1000
38 #define B_DASHED 0x2000
39 #define STYLE_MASK 0x3000
40
41 struct box_props
42 {
43 unsigned int opaque : 1;
44 unsigned int fill_color : 3;
45 unsigned int : 4;
46 unsigned int show_border : 1;
47 unsigned int border_color : 3;
48 unsigned int border_style : 2;
49 unsigned int : 2;
50 };
51
52 //把数据看作结构或 unsigned short 类型的变量
53 union Views
54 {
55 struct box_props st_view;
56 unsigned short us_view;
57 };
58
59 const char *color[8] =
60 {
61 "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"
62 };
63
64 void show_settings(const struct box_props *pb);
65 void show_setting1(unsigned short);
66 char* itobs(int n, char *ps);
67 void show_bstr(const char *str);
68
69 int main()
70 {
71 printf("size of struct box_props is %d bit\n", CHAR_BIT * sizeof(struct box_props));
72 printf("size of unsigned short is %d bit\n", CHAR_BIT * sizeof(unsigned short));
73
74 //创建 Vies 联合,并初始化 initialize struct box view
75 union Views box = {{true, YELLOW, true, GREEN, DASHED}};
76 char bin_str[8 * sizeof(unsigned int) + 1];
77
78 printf("\nOriginal box settings:\n");
79 show_settings(&box.st_view);
80 printf("\nBox settings using unsigned int view:\n");
81 show_setting1(box.us_view);
82 //printf("bits are %s\n", itobs(box.us_view, bin_str));
83 printf("bits are:\n");
84 show_bstr(itobs(box.us_view, bin_str));
85
86 box.us_view &= ~FILL_MASK; //把表示填充色的位清零
87 box.us_view |= CYAN; //重置填充色
88 box.us_view ^= OPAQUE; //切换透明位
89 box.us_view &= ~BORDER_MASK; //边框颜色位清零
90 box.us_view |= BORDER_RED;
91 box.us_view &= ~STYLE_MASK; //样式位清零
92 box.us_view |= B_DOTTED; //边框样式设置为点
93 printf("\nModified box settings:\n");
94 show_settings(&box.st_view);
95 printf("\nBox settings using unsigned int view:\n");
96 show_setting1(box.us_view);
97 //printf("bits are %s\n", itobs(box.us_view, bin_str));
98 printf("bits are:\n");
99 show_bstr(itobs(box.us_view, bin_str));
100
101 return 0;
102 }
103
104 void show_settings(const struct box_props *pb)
105 {
106 printf("Box is %s.\n", pb->opaque ? "opaque" : "transparent");
107 printf("The fill color is %s.\n", color[pb->fill_color]);
108 printf("Border %s.\n", pb->show_border ? "shown" : "not shown");
109 printf("The border color is %s.\n", color[pb->border_color]);
110
111 printf("The border style is ");
112 switch (pb->border_style)
113 {
114 case SOLID:
115 printf("solid.\n");
116 break;
117
118 case DOTTED:
119 printf("dotted.\n");
120 break;
121
122 case DASHED:
123 printf("dashed.\n");
124 break;
125
126 default:
127 printf("unknown type.\n");
128 break;
129 }
130 }
131
132 void show_setting1(unsigned short us)
133 {
134 printf("Box is %s.\n", (us & OPAQUE) ? "opaque" : "transparent");
135 printf("The fill color is %s.\n", color[(us >> 1) & 0x07]);
136 printf("Border %s.\n", (us & BORDER) == BORDER ? "shown" : "not shown");
137 printf("The border color is %s.\n", color[us >> 9 & 0x07]);
138
139 printf("The border style is ");
140 switch (us & STYLE_MASK)
141 {
142 case B_SOLID:
143 printf("solid.\n");
144 break;
145
146 case B_DOTTED:
147 printf("dotted.\n");
148 break;
149
150 case B_DASHED:
151 printf("dashed.\n");
152 break;
153
154 default:
155 printf("unknown style");
156 break;
157 }
158 }
159
160 char* itobs(int n, char *ps)
161 {
162 const static int size = CHAR_BIT * sizeof(int);
163
164 for (int i(size - 1); i >= 0; --i, n >>= 1)
165 ps[i] = (01 & n) + '0';
166
167 ps[size] = '\0';
168
169 return ps;
170 }
171
172 //以 4 位为一组,显示二进制字符串
173 void show_bstr(const char *str)
174 {
175 int i = 0;
176
177 while (str[i]) //str[i] 不是空字符
178 {
179 putchar(str[i]);
180
181 if (++i % 4 == 0 && str[i])
182 putchar(' ');
183 }
184
185 putchar('\n');
186 }