[UE5 TIL] Day 9 - C 복습/과제 작성

JungHoon Eum·2026년 3월 6일
post-thumbnail

키워드

  • 메모리 그리기
  • *, &, Right-Left Rule
  • NULL 포인터
  • switch case:
  • 포인터 & 배열
  • 함수에 값 전달/주소 전달
  • while 무한루프
  • return 0; 복수 사용

C언어 복습강의

포인터

  • 자료형* 변수명 = 메모리주소값; 포인터 선언 및 초기화
    • 변수명 쪽에 * 히면 역참조 연산자랑 심히 헷갈린다
  • Right-Left Rule: 변수명 기준 오른쪽으로~ 읽다가 왼쪽으로 읽기
    • int* (*WTF)(void); = WTF is pointer to (괄호 안이라 * 먼저 읽기) function () expecting void returning pointer* to int
  • 자료형* 변수명 = &변수명; 앞 변수는 포인터, 뒤는 실제 변수
  • 배열 역시 자료형 배열명[배열크기] 형식이라 배열명 자체도 변수다. 시작 메모리 주소를 배열 이름으로 받아낼 수 있다.
    • 함수에서 인자로 배열 받으면 값 수정도 가능
  • *는 포인터를 뜻하기도 하지만 역참조 연산자 이기도 하다.
  • 메모리 그리기:
// Main.c

#include <stdio.h>

int main(void)
{
	int X = 10, Y = 20;
	int* PtrToX = &X;

	printf("%d\n", *PtrToX);

	*PtrToX = *PtrToX * 2;
	PtrToX = &Y;

	printf("%d\n", *PtrToX);

	return 0;
}
  • 천천히 읽기
    1. int X 선언 및 10 초기화, int Y 선언 및 20 초기화
    2. int* PtrToX 포인터 선언. X 주소값 대입
    3. PtrToX 포인터가 가리키는 값(X=10) 을 10진법으로 출력 (10 출력)
    4. PtrToX 포인터가 가리키는 값에 해당 값 곱하기 2를 대입 (*PtrToX=X < 여기 10*2=20 대입)
    5. PtrToX에 Y의 주소값(&Y) 대입
    6. PtrToX 포인터가 가리키는 값(Y=20) 을 10진법으로 출력(20 출력)
    7. return X로 main함수 종료

  • NULL 포인터: define NULL((void*)0) 무슨 의미지?
  • void는 타입이 없는, NULL 은 주소값이 없음 의미

동적 할당

  • 힙 메모리: 프로그래머의 메모리 할당/해제로 관리되는 동적 할당 영역
  • malloc()free(). 반납 꼭 필수!!
  • int* Nums = (int*)malloc(10 * sizeof(int)); 이런 식으로 쓴다.
    • int 자료형 사이즈 10배의 메모리를 Nums에 할당. Nums는 포인터라 해당 메모리들의 주소값을 저장
    • 이렇게만 저장해도 Nums 는 integer pointer 니까 Nums[i] 하면 malloc()을 통해 할당된 주소들 9번지까지 방문가능

구조체

  • 기본 자료형(char, int...) 가 아닌 나만의 자료형
  • 주민등록번호, 이름 등을 모아놓고 Human 자료형 만들 고 Human[30] 만들어 사실상 생기부 만들기 할 때
  • 멤버(구조체 안에 변수들, 함수들) 에 접근할 떄 . like Human.Name
  • typedef 별명 만들기 -> C++ 에선 레퍼런스인가?

과제 진행 - 텍스트 게임 만들기

텍스트 게임 과제

  • 기본 과제를 진행하기 전에는 어디서부터 시작해야 하는지 헷갈렸지만, 나온 내용부터 하나 두개씩 넣기 시작한 후엔 생각대로 진행이 되서 재미있었다.

무한루프 생성

  • 가장 먼저 고민했던 게 액션을 취하고 나서 다시 메인으로 돌아와서 액션을 선택하는 게임플레이 루프 - 즉 무한루프를 어떻게 만들어야 할지에 대해서였다. if{} 는 일회성이고, for은 결국 끝이 존재하는 반복문이니 while을 사용하는 건 확실한데, 그 조건에 뭘 넣어야할지 고민이었는데 사실 "항상 참" 인 조건을 아무거나 넣으면 되는 것이었다. 그래서 true 를 그냥 넣고 기본 과제 내용을 만들었고, 이후엔 플레이어 스테이터스를 상승시키는 행동을 할 때마다 차감되는 actionCount 를 생성해서 10회 행동할 수 있는 메뉴를 만들었다.
  • 여기에 액션을 선택하는 입력을 키보드 1~6, 0으로 받는 거에서 착안, switch case 를 통해 입력갑 int selectMenu 값을 각 액션들과 연결시켰다.

최종 틀은 이와 같다.

while (actionCount > 0) // action Count가 남아있을 동안만 루프 돌아가게
{
    switch (selectMenu)
    {
    case 1:
    	break;
    case 2:
    ........
    case 0:
        std::cout << "Game Ended! Goodbye, World!" << endl;
        return 0;
    default:
        std::cout << "Invalid Number! Try Again" << endl;
        std::cin >> selectMenu;
        break;
    }
}

원하는 만큼 루프를, 무한대까지 굴리고 싶으면 이런 방식으로 형성하면 될 듯 하다.

  • while은 입력값 범위을 정하고 싶을 때도 사용 가능
std::cin >> enemyStatus[0];
while (enemyStatus[0] <= 100)
{
    std::cout << "Invalid Number. Set your enemy's HP: (Must be over 100)" << endl;
    std::cin >> enemyStatus[0];
}
  • return 0; 는 main 함수의 끝, 프로그램의 끝을 알리고 싶을 때 넣는 코드인데, 여태까진 main함수의 끝에 반사적으로 넣고 끝냈었지만 switch case 0: 에서 보듯 "게임 종료 조건" 을 알릴 때도 사용할 수 있다.
    • 프로그램이 종료되는 경우가 한 개 뿐이 아닐 경우 return 0; 역시 두 번 이상 쓸 수 있다. 해당 과제 내용의 경우 actionCount <=0 일 때도 return 0;, 0 입력 시에도 return 0; 을 스위치문 내부에 넣어서 거기서 종료되게 했다.
  • 함수에서 포인터는 값을 수정해야 하는 인자를 받을 때 유용하지만 (setStatus) 모든 인자를 포인터로 받을 이유는 없다. 메뉴 표시해주는 함수 void mainMenu(int status[], int* p_HPPotion, int* p_MPPotion, int* p_level, int* p_actionCount) 에선 사실 인자 수정이 없는데 너무 과하게 포인터를 쓴 감이 있어서 반성
    • status 같은 경우 배열이라 고대로 받아서 포인터처럼 내부 값 수정이 가능한 게 포인트.
  • system("cls") 인터넷 검색으로 찾은 터미널 초기화시키는 기능인데... 필요한 게 있으면 찾아쓰자. 인터넷은 위대하다.
profile
개발지망생

0개의 댓글