[Wiki] Enum flag trong C++

Hôm nọ đọc trên DNH có bài hướng dẫn về bit field

http://www.wikiwand.com/en/Bit_field

Trong bài đó cũng có phần nói về bit operators. Cái này trong IOS áp dụng tương đối nhiều, nên hôm nay mình sẽ viết 1 cái tip nho nhỏ về bitwise

Sử dụng bitwise trong lập trình nói chung làm cho code của bạn trở nên huyền bí, khó đọc. Tuy nhiên cũng có một số trường hợp áp dụng nó sẽ khiến code trông ngắn gọn, sáng sủa. Giả sử bạn làm game, nhân vật của bạn có thể có nhiều hơn một thuộc tính như CHAO, NORLMAL, MAGIC…Bạn sẽ tạo mấy biến để lưu trữ thuộc tính nhân vật?

Đây là một trường hợp tuyệt vời để áp dụng enum flag, khi đó ta chỉ cần một biến duy nhất để lưu trữ thuộc tính, tránh code rườm rà.
Giống như cách define sau

#define KEY_UP       (1 << 0)  // 000001
#define KEY_RIGHT    (1 << 1)  // 000010
#define KEY_DOWN     (1 << 2)  // 000100
#define KEY_LEFT     (1 << 3)  // 001000
#define KEY_BUTTON1  (1 << 4)  // 010000
#define KEY_BUTTON2  (1 << 5)  // 100000

Tuy nhiên mình sẽ không dùng define mà dùng enum làm cờ.

enum FLAG
{
         UNKNOW    = 0, 
         NORMAL    = 1 << 0,
         MAGIC     = 1 << 1,
         CHAO      = 1 << 2
};

Hàm main

int main(int argc, const char * argv[])
{
         FLAG flag = MAGIC | CHAO;
   
         if( flag & NORMAL)
         {
         	cout<<"Normal"<<endl;
         }   
   
         if( flag & CHAO)
         {
   		cout<<"Chao"<<endl;      	
         }
   
         return 0;
}

Tuy nhiên nếu bạn chạy ngay code này thì sẽ lỗi :D. Ta cần phải overload toán tử | (OR)

inline FLAG operator|(FLAG a, FLAG b)
{
    return static_cast<FLAG> (static_cast<int>(a) | static_cast<int>(b));
}

OK, bây giờ code đã có thể chạy được. Giải thích một chút nhé:
Khi ta thực hiện phép toán | (OR) giữa CHAO và MAGIC thì ta được (gán cờ để nhân vật mang 2 thuộc tính)

MAGIC             00000010
CHAO              00000100  
MAGIC | CHAO      00000110

Khi ta thực hiện phép toán & giữa CHAO và (MAGIC | CHAO) thì ta được (kiểm tra cờ được gán)

MAGIC | CHAO      00000110
CHAO              00000100  
MAGIC & CHAO      00000100

Kết quả giống như biến CHAO thế nên kết quả của bài trên là hiện ra CHAO.
Để biết ta gắn những cờ nào thì FLAG sẽ thực hiện phép & với cờ đó.

P/S: Lập trình ios thì các bạn sẽ thấy cái này khá nhiều.

5 Likes

@daynhauhoc Dẫn link bài này vào các bài viết C++ nhé :smile:

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?