게임은 조건문으로 이루어져 있다
e.g. HP가 0이라면, 사망 애니메이션을 출력한다.
e.g. 물건을 사고 싶은데 돈이 모자라다면, 경고창을 띄운다.
e.g. 물건을 사고 싶을 때 돈이 있다면, 인벤토리로 물건을 옮긴다.
명사 ⇒ 변수 ⇒ 메모리영역 ⇒ 램의 x 위치에서 y 만큼의 크기로 존재한다는 것을 유념하기
메모리 영역을 검사해서
⇒ 참이면 실행코드를 실행시키고
⇒ 참이 아니라면 실행코드를 실행시키지 않는다.
/*
if (메모리영역)
{
실행코드
}
*/
int GetHp()
{
return 100;
}
int main()
{
int Hp = 100;
if (Hp) // true
{
int a = 0;
}
if (GetHp()) // true
{
int a = 0;
}
if (Hp <= 0) // 비교연산자
{
int a = 0;
}
if (Hp += 10, Hp <= 0) // 괄호 안에 여러 구문을 넣을 수 있다
// 하지만 코드를 읽는 법이 어려워져 사용하지 않는 것이 좋을지도...
{
int a = 0;
}
}
{}
(메모리 영역) 안에서만 사용할 수 있다./*
HP가 100 이상일 때 정상
HP가 50~99 사이일 때 부상
HP가 10~49 사이일 때 중상
HP가 1~9 사이일 때 사망직전
HP가 0 이하일 때 사망
*/
if (Hp >= 100)
{
int a = 0; // 정상
}
else if (Hp >= 50)
{
int a = 0; // 부상
}
else if (Hp >= 10)
{
int a = 0; // 중상
}
else if (Hp >= 1)
{
int a = 0; // 사망직전
}
else
{
int a = 0; // 사망
}
// if문을 이렇게 사용하지 말자!
// 1. 값이 정확하게 일치하는 경우는 잘 없으므로 == 연산자 사용은 지양하자
if (Hp == 100)
{
int a = 0;
}
// 2. if문의 끝에 ;을 붙여버리면 if문은 바로 종료되어버리고, {}는 이름없는 공간이 되어 무조건 실행된다
int Damage = 200;
if (Damage >= 300);
{
int a = 0;
}
// 3. {} 없는 한 줄 if문은 메모리 공간이 명시적이지 않으므로 지양하자
if (true)
int a = 0;
switch (A)
{
case 0:
break;
case 10:
break;
case 20:
break;
default:
break;
}
/*
switch (A)
{
case 10:
break;
default:
break;
}
if (A == 10)
{
int a = 0;
}
else
{
int a = 0;
}
*/
case /*상수*/
과 같은 형식의 조건문이기 때문에, 사실 if문으로 완전히 대체할 수 있다.char Ch = 'A'
switch (A)
{
case 10:
int a = 0; // (1) 불가능
break;
case 10:
{
int a = 0; // (1) 가능
break;
}
case Ch; // (2) 불가능
break;
default:
break;
}
switch (Ch)
{
case 'A': // (2) 가능
break;
default:
break;
}
💡
char
자료형
⇒ 1byte 문자형
⇒''
안에서 초기화 해야 한다.
⇒ 문자임에도 숫자로 표현돼서, 참과 거짓을 구분하는 데에 사용할 수 있다. e.g.‘A’
= 65char Ch = 'A'; char T = 'B';
'A'; // 문자 상수표현식
"AAAAAA"; // 문자열 상수표현식
char String0[5] = "AAAA";
char String1[5] = { 'A', 'A', 'A', 'A', 0 };
char String1[5] = { 'A', 'A', 'A', 'A', 'A' };
=> 이렇게 강제로 넣을 수도 있지만printf_s(String1);
으로 출력하면 다섯번째 A 뒤에 이상한 글자들이 붙어 출력된다.printf
는 내부에서 0이 나올 때까지 글자를 출력하는 함수이기 때문이다.💡 배열 초기화
int Arr[5] = { 10, 20, 30, 40, 50 }; // 직접 채워줘도 되지만 int Arr[5] = {}; // 생략하면 나머지를 0으로 채워준다 int Arr0[5]; // 하지만 이렇게 쓰면 쓰레기값으로 채워주므로 지양하자
📢 잊지 말자!
1. 모든 것은 위치와 크기가 있다. ⇒ 램에서의 위치와 크기
2. 내가 제어할 수 없는 부분에 대해서는 알려고 하지도, 사용하려 하지도 말자.
e.g. 5칸짜리 배열에서 6번째, 7번째 칸에는 무엇이 있을까?
3. 코드를 작성할 때에는 꼭 중단점을 걸어 확인하는 습관을 들이자.
조건문의 메모리 영역을 검사해서
⇒ 참일 경우 → 실행코드 1번 실행 → 다시 조건문
⇒ 거짓일 경우 → while문 탈출
/*
while (메모리영역) // 조건문
{
실행코드
}
*/
#include <iostream>
int main()
{
int Count = 5;
while (Count)
{
putchar('A'); // 문자를 출력하는 함수
Count = Count - 1;
} // AAAAA
/*
이런 식으로 작성할 수도 있다.
하지만 복잡해서 알아두기만 하면 될 듯
Count = 5;
while (Count = Count - 1, Count)
{
int num = Count;
putchar('A');
} // AAAA
*/
}
// 문자열과 반복문!!!
#include <iostream>
/*
정적배열(크기가 상수로 정해진 배열)은 함수의 인자로 받을 수 없다
그래서 포인터로 받아야 하는데, 그러면 크기를 알 수가 없다
따라서 0을 만날 때까지 계속 가는 형태로 만들어준다
*/
void MyPrintf(char* _Ptr)
{
int Count = 0;
/*
char* CurPtr = (_Ptr + 0);
char CurPtr = *(_Ptr + 0);
char CurPtr = _Ptr[0];
셋 다 포인터로 배열에 접근하는 방법이지만, 마지막 방식이 가장 편하다!
*/
while (_Ptr[Count])
{
char Ch = _Ptr[Count]; // 중간중간 값을 받아서 확인해보는 습관을 들이면 좋다!!!
putchar(static_cast<int>(Ch));
Count = Count + 1;
}
}
int main()
{
char String0[5] = "AAAA";
char String1[5] = { 'A', 'A', 'A', 'A', 'A' };
MyPrintf(String0); // AAAA
MyPrintf(String1); // 0을 만날 때까지 계속 출력함
return 0;
}
일단 실행코드 1번 실행 → 조건문
⇒ 참일 경우 → 실행코드 1번 실행 → 다시 조건문
⇒ 거짓일 경우 → do while문 탈출
int main()
{
int Count = 5;
do
{
Count = Count - 1;
} while (Count);
}
초기화문 → 조건문
⇒ 참일 경우 → 실행코드 1번 실행 → 증감문 → 다시 조건문
⇒ 거짓일 경우 → for문 탈출
/*
for (size_t i = 0; i < length; i++)
{
실행코드
}
*/
#include <iostream>
int main()
{
int Value = 1;
for (
int i = 0; // 초기화문
i < 10; // 조건문
i++ // 증감문
)
{
putchar('A');
}
/*
for (; true;)
{
putchar('A');
}
while (true)
{
putchar('A');
}
*/
}
size_t
는 배우지도 않았거니와, 언리얼에서 주로 int
로 작성하므로 int
로 사용하면 된다.즉시 반복문을 종료하고 탈출하라는 의미
int Count = 0;
while (true)
{
++Count;
if (Count > 10)
{
break;
}
}
int Hp = 100;
for (int i = 0; i < 5; i++)
{
Hp -= 80;
if (Hp <= 0)
{
break;
}
}
for문 ⇒ 즉시 증감문으로 넘어가라는 의미
while문 ⇒ 즉시 조건문으로 넘어가라는 의미
for (int i = 0; i < 10; i++)
{
if ((i % 2) != 0)
{
continue;
}
int a = i; // 짝수일 때만 실행
}
int Count = 0;
while (Count < 100)
{
++Count;
if ((Count % 2) != 0)
{
continue;
}
int a = Value; // 짝수일 때만 실행
}
함수로 구현해보면 제대로 이해할 수 있다.
int Plus(int _Left, int _Right)
{
return _Left + _Right;
}
void PlusSub(int& _Left, int _Right)
{
_Left + _Right;
}
int main()
{
int Result = Plus(10, 10); // 20
// int Result = 10 + 10;
// [덧셈 대입]
int Value = 0;
PlusSub(Value, 10); // 10
// Value += 10;
// Value = Value + 10;
}
int PPFirst(int& _Value)
{
_Value = _Value + 1;
return _Value;
}
int PPBack(int& _Value)
{
int Result = _Value;
_Value = _Value + 1;
return Result;
}
int main()
{
int Value = 0;
int Result = 0;
// [전위 증감]
Result = PPFirst(Value); // 2
// Result = ++Value;
// [후위 증감]
Result = PPBack(Value); // 1
// Result = Value++;
}
C에서 사용하던 출력함수
printf
위에 마우스를 갖다대면 나오는 extern "C" inline int __cdecl printf_s( const char* Format, ...
💡 인라인 함수
inline int Test() { return 1 + 1; } int Value = Test(); int Value = 1 + 1; // 치환에 성공할 경우, 이 둘이 완전히 동일한 의미가 된다 // 함수를 불러내어 스택영역을 사용하는 것보다 컴파일 속도가 빨라진다
// Q) StringCount()와 StringReverse()를 완성시키자.
#include <iostream>
int StringCount(char* _Ptr) // 글자 수를 세는 함수
{
int i = 0;
for (i = 0; _Ptr[i] != 0; i++)
{
char Ch = _Ptr[i];
}
return i;
/*
int Count = 0;
while (_Ptr[Count])
{
++Count;
}
return Count;
*/
}
void StringReverse(char* _Ptr) // 글자의 순서를 역으로 바꾸는 함수
{
int Count = StringCount(_Ptr);
for (int i = 0; i < (Count / 2); i++)
{
putchar(static_cast<int>(_Ptr[Count - i - 1]));
}
if (Count % 2 != 0)
{
putchar(static_cast<int>(_Ptr[Count / 2]));
}
for (int i = 0; i < (Count / 2); i++)
{
putchar(static_cast<int>(_Ptr[(Count / 2) - i - 1]));
}
return;
/*
int Value = StringCount(_Ptr);
int Count = Value / 2;
for (int i = 0; i < Count; i++)
{
// 값을 확인하는 습관을 들이자
char ChF = _Ptr[i];
char ChB = _Ptr[(Value - 1) - i];
char Temp = _Ptr[i];
_Ptr[i] = _Ptr[(Value - 1) - i];
_Ptr[(Value - 1) - i] = Temp;
}
return;
*/
}
// 아래에 있는 함수는 위에 있는 함수를 사용할 수 있다!!!
int main()
{
{
char Arr[10] = "ftz";
int Result = StringCount(Arr); // 3
int a = 9;
}
{
char Arr[10] = "ABCDE";
StringReverse(Arr); // "EDCBA"
}
}
📢 코딩스탠다드
가급적 유지하자!
- 전역변수와 지역변수는 이름을 구분하여 작성하자
- 변수에는 반드시 초기값을 설정하자
- 함수의 인자 앞에는 언더바를 붙이자
- 포인터를 초기화할 때 절대 0을 사용하지 말고, nullptr을 사용하자
- 경로, 함수명, 변수명에 한글은 절대 쓰지 말자
- 프로젝트 생성 시 바탕화면은 절대 피하자
- if문을 사용할 때, 한 줄 코드일지라도 반드시 중괄호를 사용하자 (new!)