프로젝트공부아이디어
    • 2월
    • 1월
  • 30

    26. 1. 30.

  • 29

    26. 1. 29.

  • Day9

    26. 1. 27.

  • Day8

    26. 1. 26.

  • Day5

    26. 1. 23.

  • Day1

    26. 1. 22.

  • Day2

    26. 1. 22.

  • Day3

    26. 1. 22.

  • Day4

    26. 1. 22.

로딩 중...

Day4

2026. 1. 22.

무언가 만들어보기(강제성을 가지고)

파일 압축&해제 사이드 프로젝트?


색도 숫자, 문자도 숫자

C++
const char* name = "David";// "David"는 문자열, char 배열이다.// char 배열은 char[], 시작 주소를 char가 가지고 있다// 그래서 char*로 "David"를 받으면 배열의 시작 주소가 char*에 담기는 것이다//

wchar_t

동아시아 문자 지원하기 위해 추가된 와이드 캐릭터 자료형. 2바이트고 문자열 앞에 L을 붙여야만 출력이 된다 L은 Literal의 약자. Window.h 헤더를 가져오면 TEXT() 매크로로 대체할 수 있다 TEXT 매크로는 L##value로, 말그대로 L과 value를 무지성으로 붙여주는 역할. 콘솔 출력할 때도 wcin, wcout을 써야 함

Reflection?

Stack & Heap

p 포인터 변수 선언과 Person 인스턴스 동적 할당은 별개의 과정이다

C++
Person* p;p = new Person();// 이대로 main 함수가 종료되면 p는 스택에서 제거되지만 Person 인스턴스는 계속 남아있음(= memory leak)

지역 변수는 스택 안에 초기화되고 값도 스택 안에 위치한다 동적 할당 변수는 힙 안에 초기화되고, 다만 이 동적 할당 변수를 가리키는 포인터 변수는 스택 안에 초기화된다

결국 우리가 지양해야하는 것은 값 복사. 주소 복사가 타협점

Person 타입의 포인터 변수가 선언되었다는 것이 이 포인터 변수가 가리키는 Person 객체를 사용할 수 있다는 말은 아니다. 엄연히 'Person을 가리키는 포인터 변수'만 스택 세그먼트에 할당된 것이지 Person 객체가 할당된 것이 아니란 뜻.

caution! 위 상황에서 p->ShowName() 코드는 실행될 수도 있다. 왜? ShowName 멤버함수는 Person::ShowName(Person* person) 일반함수와 같다 ShowName함수 안에서 this나 멤버 데이터에 접근할 경우 크래시가 발생

Segment

프로그램이 사용하는 메모리는 세그먼트(Segment)라고 하는 여러 영역으로 나뉜다.

  • 코드 세그먼트: 컴파일된 코드가 저장되는 영역
  • 데이터 세그먼트: 전역 변수 및 정적 변수가 저장되는 영역(프로그램 시작할 때 올리고 끝날 때 해제됨)
  • 힙 세그먼트: 동적(== 실행중, Runtime)으로 할당된 변수가 저장되는 영역
  • 스택 세그먼트: 함수 매개변수, 지역 변수 및 기타 함수 관련 정보가 저장되는 영역 하지만 개념적 구분일 뿐 실상은 하나의 영역이다

폰 노이만 아키텍처

CPU(Register/L1 cache)-RAM-SSD

OS의 주목적: Hardware 자원관리

  • ROM에 설치돼있음, 부팅되면 가장 먼저 영구저장장치에 기록돼있는 데이터들을 RAM에 올려 시동을 건다

시스템 프로그래밍 = 컴구 + 운체

가상메모리

현시대는 RAM을 넘어선 메모리도 쓸 수 있는데, 이는 영구저장장치의 영역을 빌려오는 기술이다 또는 RAM에서 놀고있는 프로그램들을 영구저장장치로 밀고 공간을 확보하기도 한다 예전엔 메모리 다쓰면 바로 delete했는데, 지금은 용량 대범람의 시대인만큼 게임 로딩부터 일정부분 메모리를 통째로 잡고 프로그램이 꺼질 때까지 안놔주고 계속 쓴다(2GB = 고정 1.5GB + 유동 500MB)

Call Stack

JS의 실행 컨텍스트와 비슷함, 함수 실행을 추적함. 스택 세그먼트는 함수의 모든 매개변수, 지역 변수까지 추적하고 콜 스택은 함수만 추적

Serialization/Deserialization

구조가 다른 두 환경 간 데이터 송수신 과정

Stack

  • 스택은 자동 메모리(Auto Memory)라고도 부른다. 메모리가 자동으로 관리되기 때문이다.
  • 스택은 사용에 부담이 없고 처리 속도도 빠르지만, 메모리 크기가 고정되어 있다(1MB?). 따라서 큰 데이터를 할당하기에는 적합하지 않다.
    • Q. 만약 스택이 무한정 커지면 힙은 필요없어질까?
    • A:
  • Break Point를 사용해 콜 스택(호출 스택)을 확인하면서 디버깅을 할 수 있다.

Heap

  • new/delete ↔ malloc/free
  • 힙에 할당되는 리소스는 반드시 주소를 알아야 접근 가능하다(스택에 할당되는 데이터는 주소 몰라도 변수명으로 접근 가능함)
  • 힙에 할당되는 메모리는 연속적이지 않다. 그 때 그때 필요한 만큼의 빈 공간을 찾아 할당해준다.
  • 게임에선 힙을 많이 씀. 리소스들(사운드, 모델링 등등)이 크기 때문.
  • 힙에 할당된 메모리는 메모리 주소를 저장하는 포인터를 통해 접근한다. 포인터가 가리키는 변수의 값을 읽어오거나 값을 저장할 때는 다음과 같은 과정을 거쳐야 한다.
    • 포인터 변수에 저장된 메모리 주소로 이동한다.
    • 해당 메모리 주소에 저장된 변수의 값을 읽거나 쓴다.
  • 따라서 변수에 직접 접근하는 것보다 느릴 수 밖에 없다.
  • 하지만, 스택과 비교해 큰 데이터를 할당하는 데 문제가 없다. 큰 배열, 클래스 등을 할당해야 할 때는 힙을 사용해야 한다.

Class

class 자체가 객체는 아니다. 데이터와 함수를 한 공간에 묶기 위한 '문법'.

보통 '객체'지향 프로그래밍에서 '객체'에 꽂힌 나머지 객체의 구현방식인 '클래스', '상속', '다형성'에 매몰되기 쉬운데, 객체지향 프로그래밍의 본질은 '메세지'에 있다. 핵심은 각 캡슐화된 객체들이 메세지라는 방식으로만 소통하게 하여 개발 복잡도와 난도를 낮추는데 있다. 프로그래밍 패러다임의 본질은 현실의 문제를 소프트웨어 코드로 해결하기 위한 지난 날들의 결정체.

그래픽스 파이프라인

  1. 입력(점 집합)
  2. 점 처리 프로그램 = Vertex Shader(Shader Language) < 테셀레이션
  3. Rasterizer(GPU): 픽셀 추출(픽셀이 몇 개가 필요한지 등)
  4. Pixel Shader
  5. 출력 병합(조립)
  6. 이미지 1frame

게임수학

  1. 벡터(내적/외적)
  2. 행렬
  3. 삼각함수

역참조

C++
Player** player2 = new Player();(*player2)->Move(3, 1);

모듈화

모듈화를 하면 잃는 것들:

  • file i/o가 많아짐 = 컴파일 속도가 느려짐
    • unity build 기법(한 파일에 몰아넣기)
    • incredibuild(유료 서비스)
왼쪽 화살표2123오른쪽 화살표