daima
// 例题.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
/* 一、位字段符号常量 */
/* 边框线样式 */
#define SOLID 0
#define DOTTED 1
#define DASHED 2
/* 三原色 */
#define BLUE 4 //10进制下
#define GREEN 2
#define RED 1
/* 混合颜色 */
#define BLACK 0
#define YELLOW (RED | GREEN)
#define MAGENTA (RED | BLUE)//由红色位'或'上蓝色位组成 100 | 001 = 101
#define CYAN (GREEN | BLUE)
#define WHITE (RED | GREEN | BLUE)
/* 二、按位方法中用到的符号常量 */
#define OPAQUE 0x1//0号位 :0001 =》这个顺位1号位,二进制0号位,用来给【bool opaque】判断使用
#define FILL_BLUE 0x8 //3号位 :1000(也可以左移运算符 :1 << 3的形式)
#define FILL_GREEN 0x4 //2号位 :0100
#define FILL_RED 0x2 //1号位 :0010
#define FILL_MASK 0xE //1110 :用来表示填充色的位(方便对填充色全部取反使用)
#define BORDER 0x100 //8号位 :0001 0000 0000(作用同0号位)
#define BORDER_BLUE 0x800 //11号位 :1000 0000 0000
#define BORDER_GREEN 0x400 //10号位 :0100 0000 0000
#define BORDER_RED 0x200 //9号位 :0010 0000 0000
#define BORDER_MASK 0xE00 //控制9、10、11号位 :1110 0000 0000
#define B_SOLID 0 //“洞”的作用
#define B_DOTTED 0x1000 //12号位 :0001 0000 0000 0000
#define B_DASHED 0x2000 //13号位 :0010 0000 0000 0000
#define STYLE_MASK 0x3000 //控制12、13号位 :0011 0000 0000 0000
const char *colors[8] = { "black", "red", "green", "yellow", "blue","magenta", "cyan", "white" };
//从0 - 7 :表示8种颜色的字符
struct box_props {
bool opaque : 1;
unsigned int fill_color : 3; //【位字段】的形式表示8种颜色
unsigned int : 4; //可以用未命名的字段宽度“填充”未命名的“洞”。
//使用一个宽度为4的未命名字段迫使下一个字段与下一个整数对齐
bool show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned int : 2;
};
union Views/* 把数据看作结构或unsigned short类型的变量,一次只能使用一个 */
{
struct box_props st_view;
//使用为字段的box_props类型的结构体
unsigned short us_view;
//整形变量中的相邻位的位数,要i和结构体中的声明的位字段大小,匹配
};
void show_settings(const struct box_props *pb);
void show_settings1(unsigned short);
char *itobs(int n, char *pt);
int main(void)
{
/*创建Views联合,并初始化initialize struct box view*/
//联合体变量中对应的参数,都是上诉位字段结构体中的布尔bool和unsigned int变量对应的表现状态
//5个表现状态
union Views box = { {true, YELLOW, true, GREEN, DASHED } };
char bin_str[8 * sizeof(unsigned int) + 1];
//8 * sizeof(unsigned int) :表示int类型的位数为32位
printf("Original box settings:\n");
show_settings(&box.st_view);//函数功能实现,需要获取地址信息才行,
//因此该处要对结构体变量采用取地址操作
printf("\nBox settings using unsigned int view:\n");
show_settings1(box.us_view);
printf("bits are %s\n", itobs(box.us_view, bin_str));
box.us_view &= ~FILL_MASK; /* 把表示填充色的位清0 */
box.us_view |= (FILL_BLUE | FILL_GREEN); /* 重置填充色 1100*/
box.us_view ^= OPAQUE; /* 切换是否透明的位 */
box.us_view |= BORDER_RED;/* 错误的方法 */
box.us_view &= ~STYLE_MASK; /* 把样式的位清0 */
box.us_view |= B_DOTTED;/* 把样式设置为点 */
printf("\nModified box settings:\n");
show_settings(&box.st_view);
printf("\nBox settings using unsigned int view:\n");
show_settings1(box.us_view);
printf("bits are %s\n", itobs(box.us_view, bin_str));
//itobs同15.3.8实例中的程序一个道理(另一个文章中)
return 0;
}
//位字段
void show_settings(const struct box_props *pb)
{
printf("Box is %s.\n", pb->opaque == true ? "opaque" : "transparent");
printf("The fill color is %s.\n", colors[pb->fill_color]);
//位字段成员作数组下标使用,将索引作为数组下标了(十进制是0-7)
printf("Border %s.\n", pb->show_border == true ? "shown" : "not shown");
printf("The border color is %s.\n", colors[pb->border_color]);
printf("The border style is ");
switch (pb->border_style)
{
case SOLID:
printf("solid.\n");
break;
case DOTTED:
printf("dotted.\n");
break;
case DASHED:
printf("dashed.\n");
break;
default :
printf("unknown type.\n");
}
}
void show_settings1(unsigned short us)
{
printf("box is %s.\n", (us & OPAQUE) == OPAQUE ? "opaque" : "transparent");
printf("The fill color is %s.\n", colors[(us >> 1) & 07]);
//opaque所占的0位不管,fill color占1、2、3位1110->右移一位为0111
//与掩码07组合(0000...0000 0111),关闭除右端3位之外的所有位
//这样结果也在 0~7 的范围内,可以作为colors[]数组的索引(下标)使用
printf("Border %s.\n",(us & BORDER) == BORDER ? "shown" : "not shown");
printf("The border style is ");
switch (us & STYLE_MASK)
{
case B_SOLID: printf("solid.\n"); break;
case B_DOTTED: printf("dotted.\n"); break;
case B_DASHED: printf("dashed.\n"); break;
default: printf("unknown type.\n");
}
printf("The border color is %s.\n", colors[(us >> 9) & 07]);
//同fill color
}
char *itobs(int n, char *ps)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
//注意理解,数组在内存中以二进制存在
for (i = size - 1; i >= 0; i--, n >>= 1)
{
ps[i] = (01 & n) + '0';
}
ps[size] = '\0';
return ps;
}
图片结论
对其中小点的理解
1、洞
.
.
.
2、系统为什么一直是32位
。
.
.
3、border color中的us为什么要右移9位
.
.
…