if문은 if, else, else if 로 나뉜다.
먼저 비교문을 생각하기 전에 비교 연산자에 대해서 알아야하는데
기본적으로
== 같음
!= 다름
> 보다 큼
< 보다 작음
>= 보다 크거나 같음
<= 보다 작거나 같음
종류는 이렇게 존재한다.
if문으로 어떻게 활용하냐면
int data = 0;
if (data == 0) { // data 는 0이랑 값이 똑같나?
data = 100; // 참
}
else if (data != 100) { // 아니라면 100이 아닌가?
data = 10; // 참
}
else { // 전부 아니라면 아래 실행
data = 1;
}
비교 할때 주의 사항이 있는데 비교 할수있는 방식으로 서로 비교를 해줘야한다.
먼저 if 로 비교를 하고 바로 else 로 마무리 할수도있고 if만 적을수도있다.
사용 법은 다양 하니 적절하게 비교 문을 사용해보자.
만약 if에서 참이라서 들어갔을경우 아래 비교는 실행을 안한다.
즉 위에서 코드를 실행하면 data = 100이 된다.
swhitch 문은 if문이랑 비슷하다고 볼수있는데 코드 보면서 설명하겠다.
int data = 0;
switch (data) //data값이
{
case 0: // 0이면 아래 실행
data = 100;
break; // switch문 탈출
case 100: // 100이면 아래 실행
data = 10;
break; // switch문 탈출
default: // 걸리는 비교가 없으면 아래 실행
data = 1;
break; // switch문 탈출
}
data 값이 case랑 같은 경우 그 안에 있는 코드를 실행해 주는 구문 이다.
위에 보면 if문이랑 유사 하다.
보면 if문이랑 비슷하게 코드 설계했다.
근데 처음 보는 break; 가 생겼다.
break는 코드에 가장 가까운 바깥쪽 루프 또는 조건문의 실행을 종료 하는 명령어 이다.
여기서는 switch 문을 종료 시키고 나가게 하기 위해서 사용했다 만약에 없다고하면
비교후 0이라서 data = 100; 시키고 break로 switch 문 나가게 되는데 없다면 아래 코드도 실행 된다.
만약 아래도 없으면 default 까지 실행해버려서 data = 1이 되고 그다음 빠져 나온다.
잘 써주자 그러면 문법 실수가 아닌가 할수있는데 일부로 사용하는 경우도있다.
int data = 0;
switch (data)
{
case 0:
case 100:
case 200:
data = 1000;
break;
default:
data = 1;
break;
}
이런 경우는
int data = 0;
if (data == 0 || data == 100 || data 200) {
data = 1000;
}else {
data = 1;
}
이랑 같은 경우다 data가 0이거란 100이거나 200이면 안에 구문을 사용한다라고 사용도 가능하기 때문에 잘 써주자.
그럼 둘이 비슷한데 왜 나눠지냐고 하면 은근 조금씩 쓰는 경우가 다르기 때문에 둘다 알아두자.
가독성의 영역도 있고 실행하는 비교 조건에 따라서 좀 다른다.
삼한 연산자는 코드에 간결하게 하기 위에서 대입 할때 비교를 해버리는경우이다.
코드로 보면 이해가 오닌까 한번 보자.
int data = 0;
data == 0 ? data = 100 : data = 200;
위에 코드를 보면 먼저 if문 없이 비교를 한다
data == 0 ? 하고 물음표를 넣어서 삼항 연산자 인걸 표시하고
true 이면 data == 100 앞에문장일 실행
false 이면 data == 200 뒤에 문장을 실행 한다.
그러면 data 에 말고 다른 변수에 넣고 싶다면
int data = 0;
int a = data == 0 ? 100 : 200;
// 또는
int a = data == 0 ? data : 200;
이런 느낌으로 다양하게 사용할수있다.
난이도를 좀 올라가자 사용처도 조금 떨어지고 동작 방식도 까먹기 쉽다.
비트 연산자를 알려면 먼저 비트 쉬프트 에 대해서 알아야 하는데
저번 포스트에서 비트, 바이트 관련 알려주긴했지만 다시 정리 하겠다.
비트 시프트는 비트를 왼쪽 << 또는 오른쪽 >> 으로 밀수 있다.

위 사진 처럼 코드를 작성 해서 보자.
unsigned char c = 1;
c = c << 2; // 4
c = 8;
c = c >> 2; // 2;
이게 공식으로 보면 비트 자리를 바꿔주는경우 이다. 새로 들어온 비트는 0 이 들어온다.

코드로 한번 확인해보자.
unsigned char c = 100;
c = c << 2; // 144
근데 c = c << 2; 는 조금 그러니 이걸 대입 연산자 써서 축약 시켜보자.
unsigned char c = 100;
c <<= 2; // 144
<<= 또는 >>= 으로 축약 시킬수있다 보기에도 더 좋다.
결국 이렇게 비트 1을 미는 행동이 왼쪽으로 밀면 2, 4, 8, 16, 32로 2의 거듭 제곱으로 으로 사용할수있다.
반대로 >> 밀면 2n으로 나눈 몫 즉
<< 는 2^n == 2의 거듭 제곱, 배수
>> 는 2^n == 2^n 나눈 몫
으로 볼수있다.
비트연산을 쉽게 설명하려면 나중에 쓸건데 전처리기를 먼저 사용하겠다.
전처리기(preprocessor)는 프로그램을 컴파일할 때 컴파일 직전에 실행되는 별도의 프로그램이다.
전처리기가 실행되면 각 코드 파일에서 지시자(directives)를 찾는다.
지시자(directives)는 #으로 시작해서 줄 바꿈으로 끝나는 코드다.
전처리기는 컴파일러가 실행되기 직전에 단순히 텍스트를 조작하는 치환 역할을 하기도 하고, 디버깅에도 도움을 주며 헤더 파일의 중복 포함도 방지해주는 기능을 가진다.
이 사전 설명인데 좀 풀어서 설명하자면
컴파일러가 실행할때 전처리기 가 있으면 그 코드를 먼저 치환해서 대신 채운다.
#define HUNGRY 1
int main() {
int iStatus = HUNGRY; // int iStatus = 1;
return 0;
}
비트 곱(&), 합(|), xor(^), 역(~)
으로 사용한다.
먼저 곱부터 보자.
비트 곱은 연산 하는경우 비트 단위로 하나 씩 같은 자리를 비교해서 처리한다.
비트 단위 기준으로 비교해서 둘중 하나 라도 0이있으면 0 둘다 1이면 1이다.
비트 합은 연산 하는경우 비트 단위로 하나 씩 같은 자리를 비교해서 처리한다.
비트 단위 기준으로 비교해서 둘중 하나 라도 1이있으면 0 둘다 0이면 0이다.
xor은 비트 끼리 비교후 같은 자리에 숫자가 같으면 0 다르면 1이다.
비트 역은 비트를 그래도 0 1 숫자를 반전 시킨다 0100 1000 을 1011 0111으로 표현한다.
뭔가 논리 연산이랑 비슷하다고 볼수있는데 비트 단위에서 하는 행위이다.
이걸 어디서 사용하냐 할수도있는데 예시를 게임을 들어 보겠다.
이런 코드가 있을경우 컴파일러가 #define 을 보고 HUNGRY 라는 구문을 보면 그걸 1으로 교체 해버리고 그다음에
코드를 실행한다.
그러면 이런 디파인 구문을 사용을 하냐면
보통 게임 캐릭터가 버프나 디버프 를 넣어줄때 Status를 해줘야하는데 프로그래머가 숫자로 기억하기도 힘들고
게임이 커지면 그 양이 엄청 나다 또는 2번을 스턴으로 지정했는데 나중에 수면으로 바꾸자고 하는경우 코드를 다 찾아서 넣어줘야한다.
그런걸 define 으로 걸어뒀기 때문에 숫자를 볼 필요가 없다
또는 코드에서 전부 수정해야할때도 define 에서 하나만 바꾸면 전체 적용이 가능하기 때문에 코드 가독성 유지보수 편의성이 높아진다.
비트 합은 연산 하는경우 비트 단위로 하나 씩 같은 자리를 비교해서 처리한다.
비트 단위 기준으로 비교해서 둘중 하나 라도 1이있으면 0 둘다 0이면 0이다.
먼저 위에 보면 내 상태를 int형으로 표시 했다.
int형은 32 비트 이다.
그려면 이 상태를 조합해서 사용이 할수도있다. 그러면 이러한 상태가 한개만 아니고 여러개도 사용이 가능하기때문에
보면 int형은 한 플레이어에 32가지 상태를 표시 가능하다.
비트 1번칸은 0이면 안배고픈거 1이면 배고픈거로 사용한다고 하면
플레이어가 동시에 사용가능한 상태는 32가지 이다.

느낌이 왔다면 이걸 보면 바로 눈치 챌수 있을것이다.
한 비트 자리가
디버프가 된다. 그러면 이걸 나는 플레이어에 추가 하고싶어 일경우 대입 = 을 해도 좋은데 만약 2개이상 디버프면?
그러면 합쳐서 넣어줘야한다.
#define HUNGRY 1 //배고픔
#define THIRSTY 2 //목마름
#define TIRED 4 //피곤함
int main() {
unsigned int iStateus = 0; // 평범
iStateus |= HUNGRY; // 배고픔 추가
iStateus |= TIRED; // 피곤 추가
}
그러면 결과는 어케 될까

피곤함이랑 배고픔 둘다 체크할수있다. 한변수에서 말이다.
비트 합은 둘중 하나라도 1이면 1을 출력 하기 때문에 사용이 가능하다.
비트 곱은 연산 하는경우 비트 단위로 하나 씩 같은 자리를 비교해서 처리한다.
비트 단위 기준으로 비교해서 둘중 하나 라도 0이있으면 0 둘다 1이면 1이다.
그러면 이제 비교를 할수도있는지 확인을 해야하는데 이럴땐 어느방식으로 할수있을까?
그러경우 비트 곱으로 확인 할수있다.
둘다 비교 값 둘다 1이여야지 1을 반환하는데 이걸로 확인할수있다.

비트 곱은 비교 값이 둘다 같아야 1이기 때문에 원하는 상태만 체크 할수가 있다.
코드로 보자면
#define HUNGRY 1 //배고픔
#define THIRSTY 2 //목마름
#define TIRED 4 //피곤함
int main() {
unsigned int iStateus = 0; // 평범
iStateus |= HUNGRY; // 배고픔 추가
iStateus |= TIRED; // 피곤 추가
if (iStateus & TIRED) {
// 피곤함 처리
}
}
if 문 보면 합으로 해서 결과가 0 이면 false 이고 결국 if 문실행이 안된다.
이렇게 비트 곱으로 비교를 할수있다.
그리면 이제 디버프가 끝났으면 상태를 빼야한다. 즉 비트를 하나만 제거 하고싶다면?
xor은 비트 끼리 비교후 같은 자리에 숫자가 같으면 0 다르면 1이다.
비트를 xor은 비트끼리 비교해서 같은 자리에 숫자가 같은경우만 0 틀리면 1이다.
위에 합 곱 처럼 똑같이 생각해보면 바로 알수있다.

숫자가 같으면 0 다르면 1이닌까 피곤함이 끝났으면 비트 xor을 해주면 풀린다.
그러면 비교를 먼저 하고 넣으면 된다.
#define HUNGRY 1 //배고픔
#define THIRSTY 2 //목마름
#define TIRED 4 //피곤함
int main() {
unsigned int iStateus = 0; // 평범
iStateus |= HUNGRY; // 배고픔 추가
iStateus |= TIRED; // 피곤 추가
if (iStateus & TIRED) {
iStateus ^= TIRED; // 피곤 제거
}
}
근데 궁금한게 만약 피곤함이 없으면 넣어버리는 경우가 생긴다.
왜냐면 비교 할때 다르면 넣어버릴수도있어서 그렇다.
끝 이라고도 생각할수있는데 좀만 더 고민 해보면 사실 비교 안하고도 처리 할수있다.
이걸 사용한다면 코드 가독성도 높아지고 버그도 방지 할수도있다.
비트 역은 비트를 그래도 0 1 숫자를 반전 시킨다 0100 1000 을 1011 0111으로 표현한다.
코드를 먼저 보여주고 설명하겠다
#define HUNGRY 1 //배고픔
#define THIRSTY 2 //목마름
#define TIRED 4 //피곤함
int main() {
unsigned int iStateus = 0; // 평범
iStateus |= HUNGRY; // 배고픔 추가
iStateus |= TIRED; // 피곤 추가
iStatus &= ~TIRED; // 피곤 비트를 역으로 반전 시킨후 그걸 지금 스테이터스에 비트 곱해준다.
}
이렇게 하면 무슨일이 생기냐 하면

비트 곱 이 둘다 1이여야지 값을 1이 나오기 때문에 빼고 싶은 상태에 ~ 역으로 반전 시킨후 그값을 비트 곱으로 연산해주면
처리가 깔끔하게 된다 만약에 디버프가 없더라도 한쪽이 0이기때문에 디버프가 들어갈 일없다 방지도 가능하고 제거도 가능하고
if 둘 필요도 없기 때문에 편리하다.
int비트 처리 하고있는데 1 2 4 8 16 ... 2의 n승으로 올라가는중이다.
근데 보통 코드를 보다보면 숫자 앞에 0x 넣는경우도 있는데 16진수로 처리를 많이 한다.
예시로 한번 보자.
#define HUNGRY 1 //배고픔
#define THIRSTY 2 //목마름
#define TIRED 4 //피곤함
#define FIRE 8
#define COLD 16
#define POISON 32
#define DEBUFF1 64
#define DEBUFF2 128
#define DEBUFF3 512
#define DEBUFF4 1024
#define DEBUFF5 2048
#define DEBUFF6 4096
// 또는
#define HUNGRY 0x1 //배고픔
#define THIRSTY 0x2 //목마름
#define TIRED 0x4 //피곤함
#define FIRE 0x8
#define COLD 0x10
#define POISON 0x20
#define DEBUFF1 0x40
#define DEBUFF2 0x80
#define DEBUFF3 0x100
#define DEBUFF4 0x200
#define DEBUFF5 0x400
#define DEBUFF6 0x800
뭐가 더 보기 깔끔해보이냐 하면 아래 가 더 숫자에 규칙성이 있고 반복이 있기때문에 확인하기가 더 좋다.
이런 비트가 상태 뿐만 아니라 여러곳에서도 많이 쓰긴다 ui 관련으로 첫 페이지 보상 구매 같은 창 뜨는것도 한번도 안뜬건지 체크해서 넣고 한번도 안본거면 창 보여주고 체크 넣고 하기도하고
또는 윈도우 창 우측 상단에 있는 저런 버튼도 다 윈도우 스타일 이라고해서 만들어둔 상태이다.
이곳 저곳에서 많이 사용하기 때문에 잘 알아두자.