C++

define 과 const 의 차이(심볼릭 상수)

khkg12 2023. 8. 3. 16:11

 

심볼릭 상수란?

심볼릭 상수란 변수를 상수처럼 사용하는 것을 의미한다. 즉 상수를 기호화하여 의미 있는 이름으로 지어서 쓰는 상수를

뜻한다. 즉, 리터럴 상수와는 반대되는 개념이다.

 

심볼릭 상수의 종류

#define과 const

 

사용예시는 다음과 같다.

#define MAX_SIZE 195

const int MAX_SIZE = 195;

 

이 둘의 차이는 우선 const는 int만큼의 크기가 메모리에 저장된다. 즉 const는 공간이 할당되어있기 때문에 그 값을 추적

해서 확인할 수 있다.

 

하지만 define으로 심볼릭 상수를 선언하면 확인이 불가능하다. 전처리기를 통한 심볼릭 상수기 때문이다. 

즉 define은 전처리를 위해, 코드가 돌아가기 전에 아예 MAX_SIZE를 195로 변환시킨다는 의미를 가진다. 예를 들어 195;;;; 이렇게 붙어도 전처리기를 통한 심볼릭 상수인 define은 MAX_SIZE 를 195;;;로 인식하게끔 변환시킨다는 것이다. 

따라서 사용하는 데 있어서 const가 훨씬 압도적인 장점을 가진다. 

 

const의 사용법

const는 붙는 위치에 따라 그 의미가 다르다. 아래는 그예시다.

 

const int* nPtrA = &numA; // 이 주소안에 있는 값을 변경하지말라는 의미
int* const nPtrB = &numA; // 이 포인터변수에 들어가있는 주소를 변경하지말라는 의미 
const int* const nPtrC = &numA; // 주소도 값도 바꾸지 말라는 의미

 

참조자란?

참조자란 변수에 별명을 붙이는 것을 의미한다. 별도로 공간을 할당하는 것이 아닌, 새로운 별명을 추가했다고 보면된다.

int numA = 30;

int& nRef = numA; // 레퍼런스, 즉 numA에 대한 별명을 의미, 별도로 공간을 할당 x 그저 새로운별명을 추가했다고 보면됨


nRef = numB; // numB의 값을 넣으라는 의미, 위에서 이미정해지기 때문에 더이상 변할수없음, 항상 numA를 참조함

// 즉 처음 정해진 별명을 바꾸지않는다. 따라서 처음에 초기화시켜주지않으면 오류가 뜨는 것
cout << numA << endl; // numB의 값이 들어감

 

그렇다면 굳이 콜바이어드레스를 왜써야하나? 그 이유는 위에 설명했듯이 참조자는 한번 별명을 정하면 그 값을 변경할 수 없다. 따라서 포인터변수를 사용해야할 때에는 현재가리키고 있는 값이 변경되어야할 때 사용한다.

즉 참조자는 메모리가 할당되지 않아서 가리키는 값변경이 불가능하고, 포인터변수는 메모리를 할당하기 때문에 값을

변경가능

 

const와 참조자의 사용예제

class Player {
private:
	int num;
	int atk;
public:
	const int& GetNum() const { // 뒤에 const가 붙는건 이 함수내에선 멤버변수를 바꾸지말라는 의미로쓰임
		return num; // int&으로 리턴할건데 그 리턴에 num을 넣는다, 메모리는 차지하지않음
		// int& (이름없음) = num;
		// 따라서 메모리측면에서 효율적임
		// 하지만 게터는 변경되어선 안되니 const를 붙여주는것
		// const int& (이름없음) = num;같이 되는것 const를 붙였으니까
	}
	const int* const GetText() const { // 1c 값 2c주소 3c함수내에서 멤버변수 바꾸지말라

	}	
};

constexpr int constexprInt = n; // 런타임에선 x 컴파일타임에서만 이미 값이 세팅이되어야함 

const는 런타임이나 컴파일 둘다 상관없이 사용이 가능