열거체

-> 사용자 정의 자료형이다.

-> 열거체는 멤버로 열거형을 가진다.

-> 열거형을 토대로 상태 값 지정 시 활용한다.

 

열거체의 형태

enum 자료형이름

{

 IDLE, ATTACK, RUN, WALK

}

열거형이란?

-> 상수의 성질을 가진다.

-> 좌측부터 0으로 시작한다.

-> 이후, 1씩 증가한 상수의 성질을 가진다.

 

열거체의 선언과 초기화

PlayerState eState = 0;    // 불가능
PlayerState eState = IDLE; // 가능

 

switch에서 열거체 적용

	switch (eState)
	{
	case IDLE:
		cout << "대기 상태" << endl;
		break;
	case WALK:
		cout << "걷기 상태" << endl;
		break;
	case RUN:
		cout << "달리기 상태" << endl;
		break;
	case ATTACK:
		cout << "공격 상태" << endl;
		break;
	case DEAD:
		cout << "사망 상태" << endl;
		break;
	}

 

열거형의 상수 성질 변경

enum PlayerStance { IDLE = 1, WALK, RUN, ATTACK, DEAD, END };
	 IDLE   == 1
	 WALK   == 2
	 RUN    == 3
	 ATTACK == 4
	 DEAD   == 5
	 END    == 6

 

열거체의 크기

-> 열거형의 개수와 상관 없이 4byte의 고정된 크기를 가진다.

-> 열거체는 결국 정수형을 가진다.

(정수를 저장하기 위해서는 4byte의 공간이 있으면 된다.)

 

 

열거체의 순서는 index이므로 0부터 시작한다.

PlayerState		eState = IDLE;			// 0
PlayerState		eState = ATTACK;		// 3

 

 

열거체와 열거체 클래스(enum class) 사용

// enum

enum PlayerState{IDLE, WALK, RUN};

PlayerState eState = IDLE;

// enum class

enum class PlayerState{IDLE, WALK, RUN};

PlayerState eState = PlayerState::IDLE;

enum 보다 enum class 가 더 안전하고 가독성도 좋다고한다.

 

비트 플래그 열거형은 이름 뒤에 Flags를 붙인다.

enum class eVisibilityFlags
{
}

 

특정 크기(예를 들어, 데이터 멤버의 직렬화를 위한 크기)가 필요하지 않은 한 열거형에 크기 지정자를 추가하지 않는다.

enum class eDirection : uint8_t
{
    North,
    South
}

 

'Programming > C++ Basic' 카테고리의 다른 글

C++ 함수 포인터  (0) 2020.09.07
C++ 공용체(union)  (0) 2020.09.07
C++ 경로  (0) 2020.09.02
C++ 입출력 스트림 버퍼, 단일 문자 입/출력 함수  (0) 2020.09.02
C++ 동적 할당(C, C++기반), malloc, calloc  (0) 2020.09.01

경로


##1. 절대 경로
주체의 위치와 상관 없이 목적지가 고정되어 있다.

 

파일 위치 예)
C:\Users\aaa\Desktop\bbb\ccc\200902\Data\
-> 모든 PC에 aaa라는 폴더가 없다.

-> 현재 자신의 PC에서 폴더를 열고 상단의 주소를 복사/붙여넣기를 하는 경우는 절대 경로를 가져오는 것이다.

##2. 상대 경로
주체의 위치에 따라 목적지가 변경될 수 있다.

 

파일 위치 예)
..\Data\

-> Data파일은 항상 고정되어 있다.

-> 하지만 Data파일 앞의 경로에 있는 파일의 위치는 언제든 바뀔 수도 있다.

-> 그러므로 ..\Data\라고 표시를하여 Data파일을 주체로 놓는다.

프로그래밍에서 주소 표현 방법
큰 따옴표로 주소를 감싼다.
-> 문자열을 사용하듯이 사용한다.

##1. 역슬래쉬
-> 역슬러쉬 2개를 이용해야 폴더 접근을 뜻한다!

"C:\\Users\\aaa\\Desktop\\bbb\\ccc\\dddd\\Data\\";

##2. 슬래쉬

"../Data/";

입출력 스트림 버퍼


입출력이란?
입력과 출력을 의미한다.
프로그래밍에서 입력이란?
-> 외부의 데이터가 프로그램 내부로 흘러 들어오는 것.

프로그래밍에서 출력이란?
-> 프로그램 내부에서 외부로 데이터가 흘러 나가는 것.


스트림이란?
프로그래밍에서 스트림이란 통로라는 의미로 사용된다.
-> 가상의 통로이다.

버퍼란? 
스트림 중간에 있는 메모리 블록
데이터 송수신의 효율성 때문에 존재한다.

표준 스트림
stdin : 표준 입력 스트림. 기본 키보드 대상
stdout: 표준 출력 스트림. 기본 모니터 대상
stderr: 표준 오류 스트림. 기본 모니터 대상 // 사용하지 않을 것

 

단일 문자 출력 함수

fputc()

int_Character : 출력할 문자를 전달

FILE* _Stream : 어떤 스트림을 이용할 것인지 전달

fputc('A', stdout);

 

단일 문자 입력 함수

fgetc()

char ch = fgetc(stdin); // 입력
fputc(ch, stdout);      // 출력

여기서 abc라고 입력했을 때 출력되는 문자는 a만 나오게 된다.

이유는 간단하게 단일 문자 입출력 함수는 단일 문자만 입/출력이 가능하기 때문이다.

 

단일 문자 입출력 함수가 반환하는 값

-> 함수 호출이 성공하면 아스키코드의 정수 값을 반환한다.

-> 실패 시 EOF라는 것을 반환한다.

 

EOF란

-> End Of File의 약자.
-> 파일의 끝을 표현하기 위해 정의해 놓았다!
-> 더 이상 읽을 데이터가 없을 경우 EOF 반환하여 읽기를 끝낸다.
-> EOF는 -1의 값을 가진다.

 

반환 타입이 char가 아닌 int인 이유
-> char 자료형은 시스템 환경에 따라 unsigned로 표현될 수 있다.
-> char가 unsigned로 표현되면 -1인 EOF를 표현할 수 없게 된다. 
-> 하지만, int 자료형은 어떤 환경에서든 signed를 유지한다.
-> EOF를 표현할 수 있다.

'Programming > C++ Basic' 카테고리의 다른 글

C++ 열거체(enum)  (0) 2020.09.06
C++ 경로  (0) 2020.09.02
C++ 동적 할당(C, C++기반), malloc, calloc  (0) 2020.09.01
C++ 구조체와 포인터  (0) 2020.08.31
C++ 구조체(Struct)  (0) 2020.08.31

동적 할당

-> 메모리 영역 중 Heap 영역에 저장된다.

-> 사용자가 원할때 메모리에 등록시키고, 사용자가 원할때 메모리에서 해제할 수 있다.

-> 단, 동적 할당한 메모리를 해제하지 않을 경우 메모리 누수가 발생한다.

-> 프로그램을 종료해도 메모리에 계속해서 상주한다.

-> 동적 할당은 C방식과 C++방식으로 나눠진다.

 

C 기반 동적 할당

char*	pName = nullptr;
pName = Func();
cout << pName << endl;

pName은 Func함수가 반환하는 값을 저장한다.

-> Func함수에는 szBuff라는 지역 변수가 있다.

-> Func함수가 반환하는 값은 해당 지역 변수의 할당 주소이다.

-> Func함수가 종료되면 stack 영역을 정리하면서 지역 변수의 할당 메모리 영역을 소멸시킨다.

-> 결과적으로 pName은 소멸될 공간의 주소를 받아오는 상황이다.

 

동적 할당 방법

#1 malloc()

-> void* : 시작 주소를 반환한다.

-> 단, 해당 시작 주소는 몇 바이트만큼 어떤 형식으로 읽을지 모르는 상황이다.

-> 이를 정상적으로 사용하기 위해서는 형 변환을 진행해야 한다.

malloc 함수를 선언하고 마우스를 올려보면 (size_t Size)가 보인다.

size_t _Size는 Heap 영역에 얼마만큼 메모리 공간을 할당할지 byte단위로 크기를 전달한다.

 

malloc(4)라고 선언하면 Heap 영역에 4byte만큼 공간을 할당한다는 의미이다.

 

malloc 함수 형 변환

(int*)malloc(4);

-> 할당한 공간의 주소를 반환할 때 int*형으로 형 변환해서 반환

 

int* ptr = (int*)malloc(4);

cout << "ptr: " << ptr << endl;		// Heap 영역의 주소
cout << "*ptr: " << *ptr << endl;	// heap 영역의 주소에 할당한 값

Heap영역에 4bytes만큼 할당 후 해당 공간의 시작 주소를 반환하는데,
int*형으로 변환하여 ptr이라는 변수에 저장한다.

 

동적할당 해제 

-> 동적할당을 해제 할 때는 free() 함수를 사용하면 된다.

그런데 동적할당을 해제 했음에도 주소 값이 그대로 있다.

-> 이유는 동적 할당된 메모리를 해제는 완료하였지만 주소 값은 그대로 남아있는 상황이 발생해서 그렇다.

-> 이것을 Dangling Pointer라고 한다.

 

Dangling Pointer(위험한 주소)

-> 동적할당을 해제한다해도 변수의 주소는 그대로 남아 있다.

 

Dangling Pointer가 발생하는 경우.

-> #1 할당되지 않은 메모리 공간의 접근

-> #2 다른 변수에서 동적할당한 곳이 같은 곳을 할당 받을 경우

 

Dangling Pointer 예방 방법

-> free 함수를 호출 후 변수를 nullptr로 초기화하는 습관을 들여야한다.

calloc()
-> size_t _Count : 몇 개를 할당할 것인지 전달.
-> 동적 배열을 만들 때 사용한다.

 

4bytes 공간을 3개 할당(동적 배열) 

calloc(3, 4); 

calloc으로 동적 배열 만들기

 

int iSize = 0;

cin >> iSize;

int*	pArr = (int*)calloc(iSize, sizeof(int));

for (int i = 0; i < iSize; ++i)
	cout << pArr[i] << endl;

malloc으로 동적 배열 만들기

int iSize = 0;

cin >> iSize;

int*	pArr = (int*)malloc(sizeof(int) * iSize);

for (int i = 0; i < iSize; ++i)
		cout << pArr[i] << endl;

malloc과 calloc의 차이점
-> malloc은 쓰레기 값으로 초기화
-> calloc은 0으로 초기화가 진행된다.

 

지금까지 한 것은 C기반의 동적 할당이고,

이번에는 C++기반의 동적할당을 해보자.

 

C++ 기반의 동적 할당

new 연산자

사용 예)

new 자료형

int* ptr = new int;

Heap 영역에 자료형의 크기만큼 공간을 할당하고,

자료형의 포인터형으로 주소를 형 변환하여 반환한다.

 

동적 할당 해제

delete

delete ptr;
ptr = nullptr

C기반은 포인터를 초기화 하지 않고 동적 할당을 해제하면 주소 값이 그대로 남지만,

C++ 기반은 다른 곳에서 동적 할당할 경우에 같은 주소를 참조하지 않게 다른 곳으로 주소가 바뀐다.

이 경우 역참조를 이용하여 데이터를 다룰 경우 오류가 발생한다.

 

C++ 기반 역시 Dangling Pointer 때문에 동적 할당을 해제하고나서 포인터를 nullptr로 초기화 해줘야 한다.

 

동적할당과 동시에 초기화

-> C++ 기반은 동적 할당과 동시에 초기화가 가능하다.

int* ptr = new int(10);

C기반의 초기화

int a = 10;

C++기반의 초기화

int a(10);

 

C++기반의 동적 배열

int iSize = 0;
cin >> iSize;

int* ptr = new int[iSize];

동적 배열 해제 방법

ptr 변수로만은 Heap 영역에 할당된 공간이 배열인지 아닌지 알 수 없는 상황이다.
-> 컴파일러는 단순하게 자료형을 토대로 판단한다.

// 주소만 남기고 삭제
delete
ptr = nullptr;

// 전체 삭제
delete[] 
ptr = nullptr;

// 동적 배열 삭제
delete[] (ptr);
ptr = nullptr;

 

모든 메모리 할당은 직접 구현한 New, Delete 키워드를 통해 호출하는 것이 좋다.

'Programming > C++ Basic' 카테고리의 다른 글

C++ 경로  (0) 2020.09.02
C++ 입출력 스트림 버퍼, 단일 문자 입/출력 함수  (0) 2020.09.02
C++ 구조체와 포인터  (0) 2020.08.31
C++ 구조체(Struct)  (0) 2020.08.31
C++ 문자열 함수  (0) 2020.08.31

+ Recent posts