位字段

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

示例:位字段

#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");
	}
}

运行测试

1111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号