使用位域和掩码是不使用数据结构组合数据的常用方法。假设您正在用C语言编写国际象棋游戏。跟踪棋盘上棋子的一种方法是定义一个结构,该结构定义棋盘上每个可能的棋子及其颜色,因此每个方块都包含结构中的一个元素。例如,您可以定义结构如下:structchess_pc{intpiece;intis_black;}有了这个数据结构,你的程序就会知道每个格子里是什么棋子,以及棋子的颜色。您可以快速识别棋子是卒、车、马、象、后还是王,以及棋子是黑棋还是白棋。但是,有一种更直接的方法可以使用更少的数据和内存来跟踪此信息。我们可以存储单个int值并使用位域和掩码来标识每个方块中的棋子和颜色,而不是为棋盘上的每个方块存储两个int值。位和二进制当使用位域表示数据时,最好像计算机一样思考。让我们首先列出可能的棋子并为每个棋子分配一个编号。让我们进入下一步,用二进制表示这个数字,也就是计算机跟踪它的方式。请记住,二进制数由位组成,位为0或1。00000000:空(0)00000001:兵(1)00000010:车(2)00000011:马(3)00000100:主教(4)00000101:Queen(5)00000110:King(6)要列出棋盘上的所有棋子,我们只需要三位从右到左分别代表值1、2、4。例如,数字6在二进制中是110。6的二进制表示中的所有其他位均为0。一种更聪明的方法:我们可以使用那些始终为零的额外位来跟踪棋子是黑色还是白色。我们可以使用数字8(二进制00001000)来表示棋子是否为黑色。如果该位为1,则表示该棋子为黑色;如果为0,则表示该棋子是白色的。这称为位域,稍后我们可以使用二进制掩码将其取出。用位域存储数据要编写一个使用位域和掩码的国际象棋程序,我们可以从以下定义开始:/*pawn*/#defineEMPTY0//empty#definePAWN1//pawn#defineROOK2//rook#defineKNIGHT3//horse#defineBISHOP4//bishop#defineQUEEN5//queen#defineKING6//king/*国际象棋颜色*/#defineBLACK8//black#defineWHITE0//white/*mask*/#definePIECE7当你给一个棋子赋值时,比如初始化一个棋盘,你可以赋一个int类型的值来跟踪棋子和它的颜色。例如,要将黑车存储在棋盘的0,0位置,可以使用以下代码:intboard[8][8];..板[0][0]=黑色|ROOK;|是二元“或”(或)运算符,意思是计算机会将两个数的位进行组合。对于每个位的位置,如果一个数的任何一位为1,则该位的结果也是1。BLACK的值(8,即二进制为00001000)与ROOK的值(2,二进制为00000010)二进制OR结果为00001010,即10:00001000=8OR00000010=2________00001010=10同理,要在棋盘的6,0位置存储一个白兵,可以这样做:board[6][0]=WHITE|PAWN;所以存储的值为WHITE(0)和PAWN(1),即1.00000000=0OR00000001=1________00000001=1带掩码获取数据在下棋的过程中,程序需要知道棋子及其颜色,我们可以使用二值掩码来分隔这部分。例如,程序可能需要知道棋盘上特定方格的内容,例如board[5][3]处的数组元素。这是什么棋子,黑棋还是白棋?要识别棋子,使用二进制AND运算符将元素的值与掩码PIECE组合:intboard[8][8];intpiece;..piece=board[5][3]&PIECE;二元与运算符(&)组合两个二进制值,这样对于任何位,如果两个数中的该位均为1,则结果也为1。例如,如果board[5][3]的值为11(二进制为00001011),然后11和掩码PIECE(7,二进制为00000111)导致二进制AND二进制为00000011,即3。这代表一匹马,一匹马的值为3。00001011=11AND00000111=7________00000011=3解析棋子的颜色是一个简单的二进制与棋子值与BLACK位字段的问题。例如,您可以编写一个名为is_black的函数来确定一块是黑色还是白色:intis_black(intpiece){return(piece&BLACK);这是可行的,因为BLACK的值为8(二进制00001000)。在C语言中,任何非零值都被视为True,而零始终为False。所以is_black(board[5][3])如果5,3处的棋子是黑色,则返回真值(8),如果是白色,则返回假值(0)。位域使用位域和掩码是不使用结构组合数据的常用方法。它们值得加入程序员的“工具包”。虽然数据结构对于需要跟踪相关数据的有序编程来说是一个有价值的工具,但使用单独的元素来跟踪单个开或关值(例如棋子的颜色)的效率较低。在这些情况下,请考虑使用位域和掩码来更有效地组合数据。
