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 |