[C++ 개요] C++ 공부 이유, 컴파일, 함수와 변수의 개념

라멘커비·2023년 12월 12일
1

CPP 입문

목록 보기
1/25
post-thumbnail

개요 - 게임 프로그래밍을 하려면 C++을 익혀야 하는 이유

게임 프로그래밍을 위해 익혀야 할 언어는 무조건 C++ (또는 유니티C#)이다.

게임 프로그래밍을 위해서는 결국 언리얼, 유니티, 자체엔진 개발 중에 고르게 된다.

언리얼 → C++로 만들어짐
유니티 → C++로 만들어진 엔진에 mono(라이브러리)라는 번역기가 달려있어서 C#을 C++로 변형
자체엔진 → C++ 엔진밖에 없을 것

나중에 만들어진 언어일수록 개발하기 편하게 만들었기 때문에 편의성은 증가하나 Low Level에 대한 접근이 어려워 진다.

고급언어는 기계어로 번역된다. 높은 세대의 언어일수록 편의성이 높고, 그만큼 번역되는 기계어의 양이 많다. 번역되는 기계어 줄 수가 더 적은 C++의 속도가 빠르다.

일반적인 프로그램보다 유독 게임에서는 속도와 성능에 민감하기 때문에 속력이 더 빠를 가능성이 매우 높은 언어인 C++이 주력이 되었다.

그렇다면 C++보다 C언어가 더 빠른데 왜 C++인가?

프로젝트가 클수록 생산성 측면에서 C++이 더 합리적이다. 언어의 생산성 증가는 인간을 생각한 직관적인 문법이 있어야 가능하다. C++은 C언어와 달리 객체지향언어이기 때문에 직관적인 표현이 가능하다.
성능과 생산성이 둘 다 중요한 게임 업계에서는 Low Level과 생산성을 외줄타기(?)하는 C++을 사용하게 된 것이다.

(C++을 만든 비야네 스트롭 스트룹)

인텔에서 C교육을 해서 프로그래머들이 쏟아졌음(비야네 스트롭 스트룹의 표현). C를 제대로 사용하지 못하는 저급한 프로그래머들이 많아서 구제할 C++을 만들었다고 함..

게임 프로젝트 - 솔루션

게임 프로젝트와 프로그램은 다르다. 게임 프로젝트는 lol.exe 라는 프로그램으로 끝이 아니다. 유지보수와 여러가지 도움을 주는 다른 .exe 파일들도 만들어내야 한다.

lol 프로젝트 (=비주얼 스튜디오에서 솔루션에 해당)
lolitemEditor.exe → lol 아이템 만들고 데이터화시키는 파일 (=비주얼 스튜디오에서 프로젝트)
lolChampEditor.exe → lol 캐릭터 만들고 데이터화시키는 파일 (=비주얼 스튜디오에서 프로젝트)
lol.exe → 게임 클라이언트 파일 → (=비주얼 스튜디오에서 프로젝트)

솔루션은 exe파일을 뽑아낼 수 있는 비주얼 스튜디오의 프로젝트를 n개 모을 수 있는 단위이다. 새 프로젝트를 만들기 위해 솔루션 아래에 프로젝트를 추가한다.

  • 새 프로젝트 옵션 평소 "빈 프로젝트" 사용, 강의에서는 "콘솔 앱" 사용
  • 질문 예의 에러를 보여주면서 질문하는 것이 예의
  • 커밋 어느정도 프로젝트가 진행됐으면 자주 커밋하자. 보통 프로그래머는 2시간에 1번은 커밋함

컴파일

문법이 정확한 코드를 짜고 컴파일 과정을 거쳐서 .exe 파일이 만들어 진다.
빌드의 과정은 다음과 같다.
전처리기 > 컴파일러 > 어셈블러 > 링커

VS에서 F5 : 컴파일
Ctrl + k + c : 주석 단축키
코드 드래그하고 Alt + 방향키 : 코드 덩어리째로 이동

전처리기

전처리문 : 컴파일이 되기 전에 처리된다고 해서 전처리라고 부르고 전처리되는 구문들을 전처리문이라고 부른다.

  1. 일반적으로 실제적인 코드와는 관련이 없는 전처리문 (ex. 주석)
  2. 코드로 치환되어야 하는 전처리문 (ex. include문)

전처리기는 .exe 파일 만드는 데에 필요없기 때문에 전처리문들을 다 지워버리거나 치환한다.

전처리문 중에 #include

한마디로 코드 치환, 코드 복붙이다. #include <iostream>에서 iostream이라는 파일의 코드를 가져와서 사용할 수 있게 해준다.

  • 커서 데고 Ctrl + Shift + G : 내용 있는 곳으로 이동
    해당 단축키를 사용해서 iostream 파일의 내용을 볼 수 있다.

    내부에도 계속 #include문이 있다. 전처리기는 #include를 통해 불러오는 파일들의 코드를 모두 대신 복붙해줌으로써 개발자가 한 줄만 작성해도 되도록 해준다.

컴파일 전체 흐름

전처리기 > 컴파일러 > 어셈블러 > 링커

  • 전처리기 : 주석삭제, 코드치환(include).
  • 컴파일러 : (헤더는 컴파일 주체가 아님, cpp파일을 컴파일 하는 데 헤더 내용이 포함되게 됨)
    우리 눈에 보기에는 같은 이름인덴 같은 이름이 아닌 애들(오버로딩) 처리.
    중간 파일 .obj 파일 만들기 -> 실행 메모리 크기 결정됨.
  • 어셈블러 : 진짜 기계어 코드로 변경.
  • 링커 : 각 .obj파일에서 기계어로 번역된 것을 모두 하나로 모음. => 결과물 .exe파일

main 함수

main 함수는 프로그램이 시작하는 진입점이다. (진입점을 바꿀 수는 있지만 안 바꾸는 게 암묵적인 룰이라고 함) 즉 프로그램을 시작하는 함수이다. C++에서 행동은 함수라는 문법이라고 하기 때문에 main 진입점 함수라고 부른다. 줄여서 main 함수.
main의 의미는 프로세스를 시작한다는 의미가 된다.

main 함수의 이름을 바꿔서 컴파일해보면 이러한 에러가 뜬다.

main의 본명은 int __cdecl invoke_main(void) 혹은 ?invoke_main@@YAHXZ임을 알 수 있다. 컴퓨터가 이해하는 main의 진짜 이름이다. 이것을 네임맹글링이라고 한다.

네임맹글링(name mangling)

컴퓨터가 더 이해하기 쉽게 바꿔서 컴파일러로부터 링커로 넘기는 것
https://ko.wikipedia.org/wiki/%EB%84%A4%EC%9E%84_%EB%A7%B9%EA%B8%80%EB%A7%81

(공부할 때 참고할 사이트)

C++ 공부할 때 참고할 사이트 0 - cplusplus
C++ 공부할 때 참고할 사이트 1 - msdn
C++ 공부할 때 참고할 사이트 2 - 위키백과 혹은 C++ 파워유저 블로그
C++ 공부할 때 참고할 사이트 3 - 블로그 (게시 날짜 주의)
C++ 공부할 때 참고할 사이트 5 - Chat GPT (초보일 때는 가장 안 좋다)

프로그램의 시작과 끝, 메모리

하드디스크에 저장된 프로그램(exe파일)을 실행하면 프로그램이 램에 올라간다.

그걸 프로세스라고 한다. 실행 후 코드의 끝에 도달하면 램에서 프로세스의 메모리를 삭제한다.

1비트는 0과 1
8 비트 → 1 바이트
1024 바이트 → 1 키로 바이트
1024 키로 바이트 → 1 메가 바이트
1024 메가 바이트 → 1 기가 바이트

프로그램(실행파일)의 크기는 67KB인데 프로세스의 용량은 512KB이다?

프로그램이 종료되지 않도록 실행시키고 메모리를 확인해보았다.

int main()
{
    std::cout << "Hello World!\n";

    while (true) {

    }
}

실행파일의 크기는 67KB인데 프로세스의 용량은 512KB로 차이가 많이 난다.

프로그램 → 내가 켜지면 뭘 할거야 ex) 몬스터 100마리 만들거야
프로세스 → 몬스터 100마리 만들었어

의 차이가 있기 때문에 프로그램과 프로세스의 크기가 차이나는 것이다. 프로그램에는 코드자체가 있고, 프로세스에는 실제로 만들어진 몬스터들이 메모리를 차지하고 있기 때문이다.

함수 개념

함수는 행동 즉, 내가 하고 싶은 일이다.

행동은 C++에서 다음과 같은 문법 지키도록 설계되어 있다.

(행동의 결과) (행동의 이름) (행동의 조건)

    int main ()
    { 행동의 시작
    
	    행동의 내용
        
    } 행동의 끝

변수

몬스터 1마리와 플레이어 1명 서로 싸운다는 표현을 하고싶다.
행동이 아닌 체력이나 공격력과 같은 "상태"에 대해 숫자로의 표현이 필요하다. 이때 상태는 변수로 표현할 수 있다.

// 몬스터 1마리와 플레이어 1명 서로 싸운다는 표현하고 싶다.

    int main ()
    {
        // 보통 게임에서는 수치로 표현
        // 서로 HP를 가져서 승패를 가리고 Att(공격력)을 가져서 서로간의 강함에 차등을 준다.
        // 공격력 => 상태 => 변수
        // 싸운다 => 행동 => 함수 
        
    }

HP, Att와 같은 어떠한 상태는 변수로 표현해야 한다.
함수 내부에 있는 변수의 문법은 다음과 같다.

int Att = 10;

int : 자료형
Att : 변수명
= : 대입 연산자
10 : (내가 설정한)초기값, 혹은 리터럴값
; : 문장 마무리

프로그램 실행시 램에 프로세스로서 올라간다. 이때 코드("만들 것이다" 자체)는 코드영역에 복사가 된다. 10이라는 리터럴값도 실행 후 바뀔 수 없으므로 상수로서 코드영역에 올라간다. 실행이 되면 Att라는 변수는 스택영역에 만들어진다. 자료형의 크기만큼의 공간을 차지하게 된다.

스택영역에 실행할 것이 아무것도 남지 않게 되면 프로그램이 종료한다.

  • int
    ➡️ 자료형은 크기와 타입의 의미를 가진다.
    크기 : 램에서 몇바이트를 사용해야 한다. int는 4바이트.
    타입 : 정수다.

  • Att
    이름 : 이름은 위치를 의미하게 된다. 램에서 xxxx번지에 존재하는 메모리의 이름. 예를 들어 Att변수가 램의 96번지에 있다면 컴퓨터가 변수를 찾아가기 위해서는 Att가 결국 96이라는 숫자로 변한다..
    ➡️ 바이트 번지라는 게 되는 것.

램에서의 주소(xxxx번지)를 포인터라고 한다.

만약 Att값을 다시 덮어씌운다면 코드영역에는 상수로서의 10과 5가 모두 필요하다.
→ 프로세스의 메모리의 크기가 조금 더 커진다.

int main()
{
    int Att = 10;

    Att = 5; // Att의 값을 5로 덮어씌움
    return 0;
}
profile
일단 시작해보자

1개의 댓글

comment-user-thumbnail
2025년 1월 1일

좋은 글이네용. 잘봤습니다.

답글 달기

관련 채용 정보