본문 바로가기
C++/유튜브 어소트락 게임아카데미 C++무료강의

3. 연산자 및 전처리 구문

by GREEN나무 2025. 3. 24.
728x90

C++ 연산자 및 전처리 구문 총정리 🚀

C++ 연산자  📌

🔢 산술 연산자

연산자 설명 예제
+ 덧셈 a + b
- 뺄셈 a - b
* 곱셈 a * b
/ 나눗셈 a / b
% 나머지 a % b

 

📌 기본 연산 및 변수

int data = 10 + 10;  // 20

data + 20;  // 저장되지 않고 날아감

data = data + 20;  // 40 (data += 20 과 동일)

🔢 나머지 연산자 %

  • 정수형(📌int) 에서만 사용 가능
  • 실수형(📌double, float) 에 사용하면 컴파일 에러 발생
int data = 10. / 3.;  // 10 / 3 으로 계산됨
// 경고: ‘double’에서 ‘int’로 변환 시 데이터 손실 가능

int data = (int)(10. / 3.);  // 명시적 형변환 → 경고 없음

✅ bool 타입

  • true(1) / false(0)
  • bool은 정수형 타입 (1byte, 0 또는 1 값만 저장 가능)
bool IsTrue = 100;  // 1(true)로 저장됨

IsTrue = !IsTrue;   // 0(false)로 변경

cf. 🏛️ 제어문

✅ if, else

if (조건) {
  // 실행될 코드
} else {
  // 실행될 코드
}

✅ switch-case (break 필수!)

switch (data) {
  case 1:
    // 실행 코드
    break;
  case 2:
    // 실행 코드
    break;
  default:
    // 실행 코드
}

 

컴파일러 최적화

  • 최적화 옵션 활성화 시 절대 실행되지 않는 코드는 생성되지 않음
  • debug 모드에서는 최적화가 적용되지 않음
if (false) {
  data++;  // 컴파일러 최적화 시 이 코드는 아예 생성되지 않음
}

🔺 증감 연산자  

연산자 설명 예제
++ 1 증가 a++, ++a
-- 1 감소 a--, --a
  • 전위(++data) → 가장 먼저 적용
  • 후위(data++) → 가장 마지막(대입 연산자보다 늦게) 적용
  • 실수(double, float): 1씩 증가/감소
  • 포인터(int* p): 1단계(메모리 크기 단위) 이동 (p++, p--)
int data = 10;
++data;  // 11 (전위: 먼저 증가)
data++;  // 11 (후위: 나중에 증가)

🎭 삼항 연산자

연산자 설명 예제
?: 조건문 x = (a > b) ? a : b;
int result = (data > 10) ? 100 : 200;  
// data가 10보다 크면 100, 아니면 200

⚡ 논리 연산자

연산자 설명 예제
&& AND a && b
|| OR ||
! NOT !a

 


🖥️ 비트 연산자

연산자 설명 예제
& 비트 AND a & b
| 비트 OR a|b
^ 비트 XOR a ^ b
~ 비트 NOT ~a
<< 비트 왼쪽 이동 a << b
>> 비트 오른쪽 이동 a >> b

 

🟢 비트 시프트 연산 (<<, >>)

비트 이동 연산을 통해 값을 곱하거나 나누는 효과를 얻을 수 있음.

unsigned char byte = 10;  // 0000 1010

byte <<= 3;  // 왼쪽으로 3 이동 (10 * 2^3)
             // 0101 0000 (80)

byte >>= 3;  // 오른쪽으로 3 이동 (80 / 2^3)
             // 0000 1010 (10)

✅ 일반적인 사용법

int 변수 = a;

변수 <<= m;  // a * 2^m
변수 >>= m;  // a / 2^m (몫만 남고, 나머지는 버려짐)

 

🟢 비트 AND (&)

용도: 특정 비트가 켜져 있는지 확인하거나, 특정 비트를 끄는 데 사용
설명: 두 비트가 모두 1일 때만 1이 됨

int a = 5;   // 0101
int b = 3;   // 0011
int c = a & b; // 0001 (1)

✅ 특정 비트 확인

if (a & (1 << 2)) {  // 2번째 비트가 1인지 확인
    std::cout << "2번째 비트가 1이다." << std::endl;
}

✅ 특정 비트 끄기

a = a & ~(1 << 2);  // 2번째 비트를 0으로 만듦

🔵 비트 OR (|)

용도: 특정 비트를 켜거나, 값을 합칠 때 사용
설명: 두 비트 중 하나라도 1이면 1이 됨

int a = 5;   // 0101
int b = 3;   // 0011
int c = a | b; // 0111 (7)

✅ 특정 비트 켜기

a = a | (1 << 2);  // 2번째 비트를 1로 만듦

🟣 비트 XOR (^)

용도: 특정 비트를 토글(반전)
설명: 두 비트가 다를 때 1이 됨

int a = 5;   // 0101
int b = 3;   // 0011
int c = a ^ b; // 0110 (6)

✅ 특정 비트 토글

a = a ^ (1 << 2);  // 2번째 비트를 반전

✅ XOR 스왑 기법 (임시 변수 없이 두 수 교환)

int x = 5, y = 7;

x = x ^ y;
y = x ^ y;
x = x ^ y;

🔴 비트 NOT (~)

용도: 모든 비트를 반전
설명: 1은 0으로, 0은 1로 변경됨

int a = 5;   // 0000 0101
int c = ~a;  // 1111 1010 (-6, 2 보수 표현)

✅ 특정 비트 마스크 만들기

int mask = ~(1 << 3); // 3번째 비트만 0으로 만들기 위한 마스크

✅ 비트 반전 활용 (2의 보수 활용)

int negativeA = ~a + 1; // a의 음수 값 (-a)

🏁 비트 연산자 정리

  • 비트 연산은 마스크 처리, 최적화된 데이터 저장, 암호화, 그래픽 프로그래밍 등에 활용됨
  • 시프트 연산으로 곱셈/나눗셈 최적화 가능
  • 비트 조작으로 특정 플래그를 관리할 때 유용

🔧 C++의 전처리 구문 📜

🔹 주요 전처리 지시어

전처리 지시어 설명  예제
#define 매크로 정의 #define PI 3.14
#undef 매크로 해제 #undef PI
#include 헤더 파일 포함 #include <iostream>
#ifdef 특정 매크로가 정의되었을 때 실행 #ifdef DEBUG
#ifndef 특정 매크로가 정의되지 않았을 때 실행 #ifndef DEBUG
#if 조건부 컴파일 #if PI > 3
#else 조건부 컴파일 블록 종료 #else
#endif 조건부 컴파일 블록 종료 #endif
#pragma 컴파일러에 특정 지시 전달 #pragma once
#error 강제 컴파일 오류 발생 #error "Unsupported compiler"
#warning 경고 메시지 출력 #warning "Deprecated feature"
## 토큰 결합 연산자 #define CONCAT(a, b) a##b
# 문자열화 연산자 #define STR(x) #x

💡 전처리 지시어 예제

#include <iostream>
#define DEBUG_MODE 1
#define PI 3.14

int main() {
    #ifdef DEBUG_MODE
        std::cout << "디버그 모드 활성화\n";
    #endif
    std::cout << "PI 값: " << PI << std::endl;
    return 0;
}

 


TIP

enter는 중요하지 않음. ; 세미콜론으로 구문의 끝을 알 수 있다.

줄바꿈없어도 ;로 구문이 구분 됨.


C++ 연산자 정리 표

연산자 종류 연산자 설명 예제
산술 연산자 + 덧셈 a + b
- 뺄셈 a - b
* 곱셈 a * b
/ 나눗셈 a / b
% 나머지 a % b
대입 연산자 = 값 할당 a = b
+= 덧셈 후 할당 a += b (a = a + b)
-= 뺄셈 후 할당 a -= b (a = a - b)
*= 곱셈 후 할당 a *= b (a = a * b)
/= 나눗셈 후 할당 a /= b (a = a / b)
%= 나머지 후 할당 a %= b (a = a % b)
증감 연산자 ++ 1 증가 a++ 또는 ++a
-- 1 감소 a-- 또는 --a
비교 연산자 == 같음 a == b
!= 다름 a != b
< 작음 a < b
> a > b
<= 작거나 같음 a <= b
>= 크거나 같음 a >= b
논리 연산자 && AND a && b
|| OR a||b
! NOT !a
비트 연산자 & 비트 AND a & b
| 비트 OR a|b
^ 비트 XOR a ^ b
~ 비트 NOT ~a
<< 비트 왼쪽 이동 a << b
>> 비트 오른쪽 이동 a >> b
삼항 연산자 ?: 조건문 x = (a > b) ? a : b;
멤버 접근 연산자 . 객체 멤버 접근 obj.var
-> 포인터 멤버 접근 ptr->var
포인터 연산자 * 포인터 역참조 *ptr
& 주소 연산자 &var
형 변환 연산자 (type) C 스타일 형 변환 (int)a
static_cast<>() 정적 형 변환 static_cast<int>(a)
dynamic_cast<>() 동적 형 변환 (다형성) dynamic_cast<Derived*>(basePtr)
const_cast<>() const 속성 제거 const_cast<char*>(str)
reinterpret_cast<>() 포인터 변환 reinterpret_cast<int*>(ptr)
기타 연산자 sizeof 크기 계산 sizeof(a)
typeid 타입 정보 반환 typeid(a).name()
, 쉼표 연산자 a = (b, c)
new 동적 메모리 할당 int* p = new int;
delete 동적 메모리 해제 delete p;
new[] 배열 동적 할당 int* arr = new int[10];
delete[] 배열 동적 해제 delete[] arr;

 

C++의 연산자 우선순위

우선순위 연산자 설명 결합 방향
1 :: 범위 지정 연산자 왼쪽에서 오른쪽 (Left-to-Right)
2 ()[]->.++-- 함수 호출, 배열 인덱스, 멤버 접근, 후위 증가/감소 왼쪽에서 오른쪽
3 ++--+-!~*&sizeofnewdeletetypeid 전위 증가/감소, 부호, 논리/비트 NOT, 역참조, 주소 연산, 크기 연산, 동적 할당, 타입 정보 오른쪽에서 왼쪽
(Right-to-Left)
4 .*->* 멤버 포인터 연산자 왼쪽에서 오른쪽
5 */% 곱셈, 나눗셈, 나머지 왼쪽에서 오른쪽
6 +- 덧셈, 뺄셈 왼쪽에서 오른쪽
7 <<>> 비트 시프트 왼쪽에서 오른쪽
8 <<=>>= 비교 연산자 왼쪽에서 오른쪽
9 ==!= 동등성 비교 왼쪽에서 오른쪽
10 & 비트 AND 왼쪽에서 오른쪽
11 ^ 비트 XOR 왼쪽에서 오른쪽
12 ` ` 비트 OR
13 && 논리 AND 왼쪽에서 오른쪽
14 `   `
15 ?: 삼항 조건 연산자 오른쪽에서 왼쪽
16 =+=-=*=/=%=&= ` =^=<<=>>=` 대입 연산자
17 throw 예외 처리 throw 오른쪽에서 왼쪽
18 , 쉼표 연산자 왼쪽에서 오른쪽

 

캐릭터의 상태를 지정할 때 사용할 수 있는 단어 예시

더보기

1. 기본적인 신체 상태

건강(HEALTHY) / 아픔(INJURED, SICK)

배고픔(HUNGRY) / 배부름(FULL)

목마름(THIRSTY) / 수분충분(HYDRATED)

졸림(SLEEPY, DROWSY) / 각성(ALERT, AWAKE)

피로(FATIGUED, EXHAUSTED) / 활력(VIGOROUS, ENERGETIC)

기절(FAINTED, UNCONSCIOUS) / 정신차림(CONSCIOUS, AWARE)

출혈(BLEEDING) / 출혈 없음(STABLE)

골절(BROKEN BONE) / 정상(NORMAL)

 

 

2. 정신 상태

정신이 또렷함(FOCUSED, CLEAR-MINDED) / 혼란(CONFUSED, DISORIENTED)

기분 좋음(HAPPY, CHEERFUL) / 우울(DEPRESSED, SAD)

공포(FEARFUL, PANICKED) / 침착(CALM, RELAXED)

분노(ANGRY, ENRAGED) / 평온(PEACEFUL, CONTENT)

스트레스 받음(STRESSED, ANXIOUS) / 무덤덤(INDIFFERENT, CAREFREE)

광기(MAD, INSANE) / 제정신(SANE, STABLE)

집중(FOCUSED) / 산만(DISTRACTED)

 

 

3. 생존 및 환경 영향

더위(HOT, OVERHEATED) / 추위(COLD, FREEZING)

중독(POISONED, INTOXICATED) / 중독 없음(CLEAN, DETOXED)

감염(INFECTED) / 면역(IMMUNE, CLEAN)

방사능 오염(RADIATED) / 방사능 없음(NOT RADIATED)

익사 중(DROWNING) / 호흡 가능(BREATHING, SAFE)

탈진(EXHAUSTED) / 회복됨(RESTED, RECOVERED)

어둠 속(DARKNESS, BLINDED) / 밝음 속(IN LIGHT, VISIBLE)

 

 

4. 전투 및 행동 관련

전투 중(IN COMBAT, ENGAGED) / 전투 종료(OUT OF COMBAT, PEACEFUL)

스텔스 상태(STEALTH, HIDDEN) / 발각됨(DETECTED, VISIBLE)

무장(DISARMED, UNARMED) / 무기 장착(ARMED, READY)

기절(STUNNED, KNOCKED OUT) / 활동 가능(ACTIVE, ALERT)

속박됨(RESTRAINED, GRAPPLED) / 자유(FREE, MOBILE)

저지됨(STAGGERED, INTERRUPTED) / 행동 가능(UNSTOPPED, UNHINDERED)

기회 타이밍(OPPORTUNE, ADVANTAGEOUS) / 불리한 상태(DISADVANTAGED, VULNERABLE)

 

 

5. 기타 상태

버프(ENHANCED, BUFFED) / 디버프(DEBUFFED, WEAKENED)

축복받음(BLESSED) / 저주받음(CURSED)

광폭화(BERSERK, RAGING) / 냉정(COOL-HEADED)

도움받음(AIDED, ASSISTED) / 고립됨(ISOLATED, ALONE)

시간 느림(SLOWED, SLUGGISH) / 시간 빠름(HASTED, QUICKENED)

 

 

활용 예시

비트마스크 방식으로 상태를 정의할 경우:

#define HUNGRY 1 // 00000001

#define FULL 2 // 00000010

#define THIRSTY 4 // 00000100

#define HYDRATED 8 // 00001000

#define POISONED 16 // 00010000

#define HEALTHY 32 // 00100000

#define IN_COMBAT 64 // 01000000

#define STEALTH 128 // 10000000

✨ 비트 플래그 방식 외에 상태 정의 방법 ✨

1️⃣ 상태 정의 방식 종류

🔹 1. 비트 플래그 방식 (Bit Flags)

✅ 여러 상태를 동시에 저장할 수 있음 (비트 연산 활용) ✅ 메모리를 절약할 수 있고, 빠른 연산이 가능 ✅ 복잡한 상태 관리가 필요할 때 적합

🔹 2. 열거형 방식 (Enum)

✅ 상태를 열거형으로 정의하여 가독성이 좋음 ✅ 단일 상태 관리에 적합 (복합 상태에는 적합하지 않음)

🔹 3. 구조체 방식 (Struct)

✅ 여러 상태 값을 개별 변수로 저장할 수 있음 ✅ 관리가 쉬우나, 메모리 사용이 많아질 수 있음

🔹 4. 배열 방식 (Array/Set)

✅ 상태를 배열 또는 집합(Set) 형태로 저장 ✅ 특정 상태를 쉽게 추가/제거 가능 ✅ 검색 연산이 필요하므로 속도가 상대적으로 느릴 수 있음


2️⃣ 상태 정의 방법별 예제

🟢 1. 비트 플래그 (Bit Flags) 방식

#include <stdio.h>

// 상태 정의 (비트 플래그 방식)
#define HUNGRY   0x01 // 0000 0001
#define THIRSTY  0x02 // 0000 0010
#define POISONED 0x04 // 0000 0100
#define IN_COMBAT 0x08 // 0000 1000

int main() {
    unsigned int state = 0; // 초기 상태 (아무 상태도 없음)
    
    // 상태 추가
    state |= HUNGRY | THIRSTY;
    printf("현재 상태: %X\n", state);
    
    // 상태 제거
    state &= ~HUNGRY;
    printf("배고픔 제거 후 상태: %X\n", state);
    
    // 상태 확인
    if (state & THIRSTY) {
        printf("목마른 상태입니다.\n");
    }
    
    return 0;
}

사용 상황: 게임 캐릭터의 다양한 상태를 효율적으로 관리할 때, 메모리를 절약하면서 여러 상태를 동시에 관리할 때


🟢 2. 열거형 (Enum) 방식

#include <stdio.h>

// 열거형으로 상태 정의
typedef enum {
    STATE_HUNGRY,
    STATE_THIRSTY,
    STATE_POISONED,
    STATE_IN_COMBAT
} CharacterState;

int main() {
    CharacterState state = STATE_HUNGRY; // 초기 상태: 배고픔
    
    // 상태 변경
    state = STATE_THIRSTY;
    printf("현재 상태: %d\n", state);
    
    // 상태 확인
    if (state == STATE_THIRSTY) {
        printf("목마른 상태입니다.\n");
    }
    
    return 0;
}

사용 상황: 한 번에 하나의 상태만 유지해야 하는 경우, 코드 가독성을 높이고 싶을 때


🟢 3. 구조체 (Struct) 방식

#include <stdio.h>

// 구조체로 상태 정의
typedef struct {
    int isHungry;
    int isThirsty;
    int isPoisoned;
    int isInCombat;
} Character;

int main() {
    Character player = {1, 0, 0, 1}; // 배고픔, 전투 중
    
    // 상태 확인
    if (player.isHungry) {
        printf("배고픈 상태입니다.\n");
    }
    
    // 상태 변경
    player.isHungry = 0;
    printf("배고픔 제거\n");
    
    return 0;
}

사용 상황: 상태가 많고, 각 상태를 독립적으로 관리해야 할 때, 개별 상태의 값을 조정해야 할 때


🟢 4. 배열/집합 (Array/Set) 방식

#include <stdio.h>
#include <string.h>

#define MAX_STATES 10

const char* STATES[] = {"HUNGRY", "THIRSTY", "POISONED", "IN_COMBAT"};

// 상태 리스트 관리
typedef struct {
    char states[MAX_STATES][20];
    int count;
} StateList;

// 상태 추가
void addState(StateList *list, const char* state) {
    if (list->count < MAX_STATES) {
        strcpy(list->states[list->count], state);
        list->count++;
    }
}

// 상태 출력
void printStates(StateList *list) {
    printf("현재 상태: ");
    for (int i = 0; i < list->count; i++) {
        printf("%s ", list->states[i]);
    }
    printf("\n");
}

int main() {
    StateList player = {.count = 0};
    
    addState(&player, "HUNGRY");
    addState(&player, "IN_COMBAT");
    
    printStates(&player);
    
    return 0;
}

사용 상황: 동적으로 변하는 상태를 관리해야 할 때, 특정 상태를 쉽게 추가/삭제해야 할 때


🔍 비교 요약

방식 장점 단점 사용 예시
비트 플래그 빠르고 메모리 절약 해석이 어려움 게임 캐릭터 상태 관리
열거형 (Enum) 가독성이 좋음 여러 상태 동시 관리 어려움 단일 상태 변경이 필요한 경우
구조체 (Struct) 개별 변수로 관리 가능 메모리 사용 증가 상태별 세부 조정 필요할 때
배열/집합 (Array/Set) 상태 추가/삭제 유연 검색 시 속도 저하 가능 가변적인 상태 관리

 

 

'C++ > 유튜브 어소트락 게임아카데미 C++무료강의' 카테고리의 다른 글

6. 구조체(Structure)  (0) 2025.03.30
5. 배열  (0) 2025.03.26
4 함수  (0) 2025.03.26
2. 자료형  (0) 2025.03.17
C언어/C++ 무료강의 - 1_인트로  (0) 2025.03.14