코딩 학습

C++ 기초 - 참조

이개 2026. 4. 4. 01:21

참조(Reference)

이미 존재하는 변수명에 또 하나의 별명을 붙여주는 문법. 즉, 변수의 별명을 지어주는 문법입니다.

int Number = 10;
int& Num = Number;

 

참조는 NULL 대입 불가.

포인터는 NULL 대입 가능.

int& Reference = NULL; 
	// 컴파일 에러.
	// 참조는 반드시 존재하는 변수를 참조해야 함.

참조는 선언과 동시에 반드시 초기화.

포인터는 초기화 안해도 컴파일 가능.

int& Reference; // 컴파일 에러

참조는 참조하는 대상을 바꿀 수 없음.

 

 

Reference와 Swap() 함수

// Main.cpp

#include <iostream>

void SwapWithValue(int LHS, int RHS)
{
	std::cout << "SwapWithValue() has been called." << std::endl;
	int Temp = LHS;
	LHS = RHS;
	RHS = Temp;
}

void SwapWithPointer(int* LHS, int* RHS)
{
	std::cout << "SwapWithPointer() has been called." << std::endl;
	int Temp = *LHS;
	*LHS = *RHS;
	*RHS = Temp;
}

void SwapWithReference(int& LHS, int& RHS)
{
	// Q. LHS와 RHS에 nullptr이 전달 될 수 있을까?
	// Q. LHS와 RHS에도 포인터 연산이 가능할까?
	std::cout << "SwapWithReference() has been called." << std::endl;

	int Temp = LHS;
	LHS = RHS;
	RHS = Temp;
}

int main(void)
{
	int A = 10, B = 20;

	std::cout << "A: " << A << " // B: " << B << std::endl;
	SwapWithValue(A, B);
	std::cout << "A: " << A << " // B: " << B << std::endl;
	SwapWithPointer(&A, &B);
	std::cout << "A: " << A << " // B: " << B << std::endl;
	SwapWithReference(A, B);
	std::cout << "A: " << A << " // B: " << B << std::endl;

	return 0;
}

 

 

// Main.cpp

struct Script
{
public:
	char ScriptString[2048];

};

void Print01(Script InScript)       // 아파트 한 개 호실(10톤) Vs. 집문서(10g)
{

}

void Print02(Script* InPtrToScript) // 불필요한 값 복사를 막을 수 있습니다.
{

}

void Print03(Script& InRefToScript) // 참조로도 불필요한 값 복사를 막을 수 있습니다.
{

}

int main(void)
{
	Script NPC01Script = Script();
	Print01(NPC01Script);
	Print02(&NPC01Script);
	Print03(NPC01Script);

	return 0;
}

 

 

참조를 쓰는 경우와 포인터를 쓰는 경우

int* PtrToA;

int A = 10; 
int& RefToA = A;
// 1. 포인터는 선언과 동시에 초기화 안해줘도됩니다. 
//    참조는 선언과 동시에 무조건 초기화 해줘야합니다. 

int* PtrToA = nullptr;

int& RefToA = nullptr; // 컴파일에러.
// 2. 포인터는 nullptr을 값으로 저장 할 수 있습니다.
//    참조는 nullptr을 값으로 저장 할 수 없습니다.

*(PtrToA + 1); // 너 뭐 돼?

int A = 10;
int B = 20; 
int& RefToA = A;
RefToA = B;    // 어떤 일이 벌어질까요?
// 3. 포인터는 "포인터 연산"이 가능합니다. 
//    참조는 연산 자체가 없습니다. 다른 메모리 주소를 가르키는게 불가능합니다.
// Main.cpp

void Swap(char* InPtrToScript, const int InLength)
{
	char Temp = *InPtrToScript;
	*InPtrToScript = *(InPtrToScript + (InLength - 1));
	*(InPtrToScript + (InLength - 1)) = Temp;
		// 포인터는 연산이 가능하기에 알고리듬과 궁합이 잘맞습니다. 
		// ex) 문자열 뒤집기, ...
}

int main(void)
{
	char String[16] = { 'a', 'b', 'c', '\0', };

	Swap(String, 3);

	return 0;
}

 

참조는 안전하지만 자유도가 떨어지고, 포인터는 안전하지 않지만 자유도가 높다.

모든 상황에서 참조를 사용하다가 필요에 따라 포인터로 변경하는 것도 좋다.

 

 

NULL 값

// Human.h
bool IsFriend(const char* InName);
bool IsFriend(int InID);

// Main.cpp
bool IsFriend = Human01->IsFriend(NULL); 
	// 어떤 함수가 호출될까요? IsFriend(int InID);가 호출됩니다.
	// NULL의 정의를 보면, 정수 0으로 해석될 수 있는 상수이기 때문입니다.
	// ex) #define NULL (0), ...

 

nullptr

NULL은 정수 0으로 해석될 수 있지만, nullptr은 정수로 변환되지 않도록 설계되어 있어서 포인터 상수로 사용 할 수 있다.

int Number = NULL;              // compile.
int* PtrToNumber = NULL;        // compile.

int AnotherNumber = nullptr;    // compile error.
int* PtrToAnotherNumber = nullptr; // compile.

 

보통 nullptr로 쓴다.

'코딩 학습' 카테고리의 다른 글

C++ 기초 - 객체지향 프로그래밍  (0) 2026.03.09