A good way to understand bitmasks is an example, so I will give it. Let's say we have an array of structures:
struct my_struct {
int foo;
int bar;
};
struct my_struct array_of_structs[64];
, , . - used .
struct my_struct {
int foo;
int bar;
char used;
};
- . 64, 64- . , , , , .
unsigned long long bitmap;
, , 0 , , 1 . i :
bitmap = bitmap | (1ULL << i);
:
bitmap |= (1ULL << i);
(1ULL << i) , 0, i - , bitmap | (1ULL << i) bitmap, , i th ( , ), bitmap |= (1ULL << i);, , i th 1 , . i - , i th , - i - .
, , i , &:
if(bitmap & (1ULL << i)) {
// i is used
}
else {
// i is not used
}
bitmap & (1ULL << i) , , , i th bitmap.
, , :
bitmap = bitmap & ~(1ULL << i);
bitmap &= ~(1ULL << i);
~(1ULL << i) 64 ( , unsigned long long - 64 ) , 1, i th . bitmap, , bitmap, , i th 0.
, bitmap vs a used. , , , , , - . , , , , - . , , . , , , , . , .
. . , , .
struct player {
unsigned long long flag;
};
, , , , . , .
#define PLAYER_JUMPING (1ULL << 0)
#define PLAYER_SWIMMING (1ULL << 1)
#define PLAYER_RUNNING (1ULL << 2)
#define PLAYER_DEAD (1ULL << 3)
, .
struct player my_player;
my_player.flag |= PLAYER_JUMPING;
my_player.flag &= ~PLAYER_SWIMMING;
if(my_player.flag & PLAYER_RUNNING)
, , , : ^. .
my_player.flag = my_player.flag ^ PLAYER_DEAD; // If player was dead now player is not dead and vise versa
, :
my_player.flag ^= PLAYER_DEAD; // If player was dead now player is not dead and vise versa
, , , .. x ^ 0 == x .
. , , , :
if(my_player.flag & (PLAYER_RUNNING | PLAYER_JUMPING)) // Test if the player is running or jumping
, (PLAYER_RUNNING | PLAYER_JUMPING) , , , .