示例:位字段
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//提供CHAR_BIT的定义,CHAR_BIT表示每字节的位数
#include <limits.h>
//C99定义了bool、true、false
#include <stdbool.h>
/////////////////////////////////////////////////////////////////////////////////////////////
/*
位字段:
操控位的第2种方法是位字段(bit field)。位字段是一个signed int或unsigned int类型变量中
的一组相邻的位(C99或C11新增了_Bool类型的位字段)。位字段通过一个结构声明来建立,该结构声明
为每个字段提供标签,并确定该字段的宽度。
*/
//下面的声明建立了一个4个1位的字段
struct {
unsigned int autfd : 1;
unsigned int bldfc : 1;
unsigned int undln : 1;
unsigned int itals : 1;
} prnt; //变量prnt被储存在int大小的内存单元中,但是在本例中只使用了其中的4位
//下面创建了两个2位的字段和一个8位的字段
struct {
unsigned int code1 : 2;
unsigned int code2 : 2;
unsigned int code3 : 8;
} prcode;
/*
如果声明的总数超过了一个unsigned int类型的大小,则会用到下一个unsigned int类型的存储位置。
一个字段不允许跨越两个unsigned int之间的边界。编译器会自动移动跨界的字段,保持unsigned int
的边界对齐。一旦发生这种情况,第1个unsigned int中会留下一个未命名的“洞”。
可以用未命名的字段宽度“填充”未命名的“洞”。使用一个宽度为0的未命名字段迫使下一个字段与下一
个整数对齐:
*/
struct {
unsigned int field1 : 1;
//field1与field2之间,有一个2位的空隙
unsigned int : 2;
unsigned int field2 : 1;
unsigned int : 0; //迫使下一个字段与下一个整数对齐
//field3将储存在下一个unsigned int中
unsigned int field3 : 1;
} stuff;
/*
字段储存在一个int中的顺序取决于机器。在有些机器上,存储的顺序是从左往右,而在另一些机器
上,是从右往左。另外,不同的机器中两个字段边界的位置也有区别。由于这些原因,位字段通常都不容易
移植。尽管如此,有些情况却要用到这种不可移植的特性。
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
/* 线的样式 */
#define SOLID 0 //实线
#define DOTTED 1 //点线
#define DASHED 2 //虚线
/* 三原色 */
#define BLUE 4
#define GREEN 2
#define RED 1
/* 混合色 */
#define BLACK 0
#define YELLOW (RED | GREEN)
#define MAGENTA (RED | BLUE)
#define CYAN (GREEN | BLUE)
#define WHITE (RED | GREEN | BLUE)
const char * colors[8] = {"black", "red", "green", "yellow","blue", "magenta", "cyan", "white"};
//声明一个描述方框属性的结构体
struct box_props {
bool opaque : 1; //是否透明; 或者 unsigned int (C99以前)
unsigned int fill_color : 3;//填充色
unsigned int : 4;
bool show_border : 1;//是否显示边框; 或者 unsigned int (C99以前)
unsigned int border_color : 3; //边框颜色
unsigned int border_style : 2; //边框样式
unsigned int : 2;
};
void show_settings(const struct box_props * pb);
int main(int argc, char* argv[])
{
//由于每个字段恰好为1位,所以只能为其赋值1或0
prnt.itals = 0;
prnt.undln = 1;
//要确保所赋的值不超出字段可容纳的范围
prcode.code1 = 0;
prcode.code2 = 3;
prcode.code3 = 102;
/* 创建并初始化box_props结构 */
struct box_props box = { true, YELLOW, true, GREEN, DASHED };
printf("Original box settings:\n");
show_settings(&box);
box.opaque = false;
box.fill_color = WHITE;
box.border_color = MAGENTA;
box.border_style = SOLID;
printf("\nModified box settings:\n");
show_settings(&box);
system("pause");
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]);
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");
}
}
运行测试