프로그래밍 C언어

비트 단위 연산자 (Bitwise Operators)

게임첫걸음 2024. 8. 18. 22:05
#include <stdio.h>

enum EEquip			//enum문은 열거형 정의 시 사용
{
	kEmpty = 0, kHead = 1, kChest = 2, kLArm = 4, kRArm = 8, kLLeg = 16, \
	kRLeg = 32, kWeapon = 64, kShield = 128
	//각자 비트 제공
};

void PrintEquip(unsigned char _equip);		//반환값이 필요없는 함수는 void 사용

void main()
{
	//비트 단위 연산자(Bitwise Operators)	//비트 단위로 조작할 때 사용.
	char lhs = 3;						//정수 3값 비트단위연산자로 2진수 사용
	char rhs = 5;						//정수 5값 비트단위연산자로 2진수 사용
	//Bitwise AND(&)					//00000011 vs 00000101
	printf("lhs & rhs: %d\n", lhs & rhs);	//둘다 참이어야 참			00000001
	//Bitwise OR(|)
	printf("lhs | rhs: %d\n", lhs | rhs);	//둘 중 하나라도 참이면 참	00000111
	//Bitwise XOR(^)
	printf("lhs ^ rhs: %d\n", lhs ^ rhs);	//두 값이 다르면 참		00000110
	//Bitwise NOR(~)
	printf("~lhs: %d\n", ~lhs);				//참 -> 거짓, 거짓 -> 참	11111100

	//연산자 중 가장 처리 속도가 빠름. 2의 거듭제곱으로 곱 또는 나누기에 사용.
	//Left 쉬프트 연산자(Left Shift)		//한 칸 갈 때마다 값이 두 배
	printf("lhs << 2: %d\n", lhs << 2);		//3의 4곱으로 12
	//Right 쉬프트 연산자(Right Shift)		//한 칸 갈 때마다 값이 1/2배
	printf("rhs >> 1: %d\n", rhs >> 1);		//5의 2나누기로 나머지 제외 2

	//Bit Flag
	unsigned char equip = kEmpty;			//시작은 아무것도 없이 시작
	equip |= kHead | kChest | kLArm | kRArm | kLLeg | kRLeg | kWeapon | kShield;
	PrintEquip(equip);

	//무기, 방패 아이템 잃은 상태
	equip ^= kShield ^ kWeapon;
	PrintEquip(equip);
}

void PrintEquip(unsigned char _equip)
{
	if (_equip == kEmpty)
	{
		printf("Empty!\n");
		return;
	}

	printf("Head ( %c )\n", (_equip & kHead) > 0 ? 'O' : 'X');
	printf("Chest ( %c )\n", (_equip & kChest) > 0 ? 'O' : 'X');
	printf("LArm ( %c )\n", (_equip & kLArm) > 0 ? 'O' : 'X');
	printf("RArm ( %c )\n", (_equip & kRArm) > 0 ? 'O' : 'X');
	printf("LLeg ( %c )\n", (_equip & kLLeg) > 0 ? 'O' : 'X');
	printf("RLeg ( %c )\n", (_equip & kRLeg) > 0 ? 'O' : 'X');
	printf("Weapon ( %c )\n", (_equip & kWeapon) > 0 ? 'O' : 'X');
	printf("Shield ( %c )\n", (_equip & kShield) > 0 ? 'O' : 'X');
	printf("\n");
}

 
비트 단위 연산자는 비트 단위를 조작할 때 사용하는 연산자입니다. 여기선 enum문을 사용하였는데 enum문은 데이터 열거를 할 때 사용합니다. 밑에 데이터들에 각자에 할당되는 비트값을 전달했습니다.
enum EEquip
{
kEmpty = 0, kHead = 1, kChest = 2, kLArm = 4, kRArm = 8, kLLeg = 16, kRLeg = 32, kWeapon = 64, kShield = 128
};
2진수로 표현되기 때문에 kEmpty를 제외하고 00000000 (8비트)에 각자 할당되는 데이터를 전달한 겁니다. 

2진수에 해당되는 비트값을 각 데이터에 할당

enum문에 대한 얘기는 이 정도로 하고 먼저 lhs, rhs 관련 비트 단위 연산자를 다루고 이후 enum에서 정의한 데이터 관련 함수를 다룰 때 더 깊이 다루겠습니다.
 
void main()
{
char lhs = 3; 
char rhs = 5; 
//Bitwise AND(&) //00000011 vs 00000101
printf("lhs & rhs: %d\n", lhs & rhs); //둘다 참이어야 참 00000001
//Bitwise OR(|)
printf("lhs | rhs: %d\n", lhs | rhs); //둘 중 하나라도 참이면 참 00000111
//Bitwise XOR(^)
printf("lhs ^ rhs: %d\n", lhs ^ rhs); //두 값이 다르면 참 00000110
//Bitwise NOR(~)
printf("~lhs: %d\n", ~lhs); //참 -> 거짓, 거짓 -> 참 11111100

//연산자 중 가장 처리 속도가 빠름. 2의 거듭제곱으로 곱 또는 나누기에 사용.
//Left 쉬프트 연산자(Left Shift) //한 칸 갈 때마다 값이 두 배
printf("lhs << 2: %d\n", lhs << 2); //3의 4곱으로 12
//Right 쉬프트 연산자(Right Shift) //한 칸 갈 때마다 값이 1/2배
printf("rhs >> 1: %d\n", rhs >> 1); //5의 2나누기로 나머지 제외 2
 
lhs와 rhs 각각 정수형 값 3, 5로 초기화했습니다. 그러나 출력문에서 사용된 비트 단위 연산자(&, |, ^, ~, <<, >>)들로 인해 정수형 값이 2진수 값으로 연산된 후 그 값을 %d, 10진수로 표현됩니다.
3은 00000011 / 5는 00000101로 표현됩니다. 주석 설명에 따라 출력값을 각각 나타내면 다음과 같습니다.

 

  • &: AND연산자로 둘 다 참이어야 참 (2진수에서 참은 1을 뜻합니다. 3과 5의 2진수에서 중복된 자리의 1값이 존재하면 그 자리만 1 나머진 0으로 표현합니다. 3과 5는 중복되는 1이 2의0승만 1입니다. 00000001이 되고 %d로 1이 출력됩니다.
  • | : OR연산자로 둘 중 하나만 참이어도 참 (3과 5의 2진수에 따라 00000111이 되고 이를 %d로 7이 출력됩니다.
  • ^ : XOR연산자로 두 값이 다르면 참 (3과 5의 2진수에 따라 00000110이 되고 이를 %d로 6이 출력됩니다.
  • ~ : NOR연산자로 참은 거짓, 거짓은 참 (이건 매개변수값을 하나만 보유하고 lhs값인 3의 2진수에 따라 11111100이 되고 이를 %d로 -4가 출력됩니다.

'프로그래밍 C언어' 카테고리의 다른 글

공용체 (Union)  (0) 2024.08.20
구조체 (Structure)  (0) 2024.08.20
동적 메모리 할당 (Dynamic Memory Allocate)  (0) 2024.08.18
문자열 (String)  (0) 2024.08.16
함수 (Function)  (0) 2024.08.14