Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C/C++ 참조(Reference)와 포인터(Pointer)의 차이점과 사용 기준 완벽 정리

참조 변수(Reference Variable)

참조 변수는 이미 존재하는 변수에 붙이는 다른 이름(별칭)입니다. 한 번 어떤 변수와 연결되면 다른 변수를 가리키도록 바꿀 수 없으며, 선언과 동시에 반드시 초기화해야 합니다. 또한 참조 변수는 NULL 값을 가질 수 없습니다. 참조 변수를 선언할 때는 '&' 연산자를 사용합니다.

참조 변수의 기본 문법은 다음과 같습니다.

datatype variable_name;               // 일반 변수 선언
datatype& refer_var = variable_name;  // 참조 변수 선언

각 구성 요소의 의미는 다음과 같습니다.

datatype − int, char, float 등 변수의 자료형

variable_name − 사용자가 지정한 원본 변수의 이름

refer_var − 원본 변수를 가리킬 참조 변수의 이름

다음은 참조 변수를 사용하는 예제입니다.

예제

#include <iostream>
using namespace std;

int main() {
    int a = 8;
    int& b = a;   // a의 참조(별칭) b 생성

    cout << "변수 a의 값: " << a;
    cout << "\n참조 변수 b의 값: " << b;

    return 0;
}

출력 결과

변수 a의 값: 8
참조 변수 b의 값: 8

b는 a의 또 다른 이름에 불과하므로, 두 값이 동일하게 8로 출력됩니다.

포인터(Pointer)

포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 변수에 메모리가 할당되면 포인터는 해당 변수가 위치한 주소를 가리키며, '*ptr'처럼 역참조 연산자를 사용해 주소에 저장된 실제 값에 접근할 수 있습니다. 참조와 달리 포인터는 선언 후에 초기화할 수 있고, 실행 중에 가리키는 대상을 바꾸거나 NULL을 가질 수도 있습니다.

포인터의 기본 문법은 다음과 같습니다.

datatype *variable_name;

datatype − int, char, float 등 변수의 자료형

variable_name − 사용자가 지정한 포인터 변수의 이름

다음은 포인터를 사용하는 예제입니다.

예제

#include <stdio.h>

int main() {
    int a = 8;
    int *ptr;

    ptr = &a;   // 포인터에 변수 a의 주소 저장

    printf("변수의 값: %d\n", a);
    printf("변수의 주소: %p\n", ptr);
    printf("포인터가 가리키는 값: %d\n", *ptr);

    return 0;
}

출력 결과

변수의 값: 8
변수의 주소: 0x7ffd5a1c4b64
포인터가 가리키는 값: 8

주소 값은 실행 환경과 실행 시점마다 달라집니다. 참고로 주소를 출력할 때는 %d가 아닌 %p 형식 지정자를 사용하는 것이 올바른 방법입니다.

참조 변수 vs 포인터: 핵심 차이

구분참조(Reference)포인터(Pointer)
초기화선언 시 반드시 초기화선언 후 초기화 가능
대상 변경불가능가능
NULL 허용불가능가능
값 접근 방식원본처럼 직접 사용* 연산자로 역참조 필요
주소 확인& 연산자로 확인포인터 자체가 주소를 저장

그렇다면 언제 무엇을 사용해야 할까?

두 기능 모두 변수에 간접적으로 접근한다는 공통점이 있지만, 상황에 따라 더 적합한 도구가 다릅니다.

참조(Reference)가 적합한 경우

  • 함수에 인자를 전달하면서 불필요한 복사 비용을 줄이고 싶을 때
  • 가리키는 대상이 절대 NULL이 아니고 중간에 바뀌지 않는다고 보장될 때
  • 역참조 문법 없이 원본처럼 자연스럽게 사용하여 코드 가독성을 높이고 싶을 때

포인터(Pointer)가 적합한 경우

  • '대상이 없는 상태'를 표현해야 할 때 (NULL 활용)
  • 프로그램 실행 중에 가리키는 대상을 변경해야 할 때
  • new/malloc 같은 동적 메모리 할당이나 배열, 자료구조를 다룰 때
  • C 언어로 작업할 때 — C에는 참조라는 개념이 존재하지 않습니다.

정리하면, "항상 유효한 단일 대상만 가리킨다면 참조를, 유연성·NULL 처리·동적 메모리 관리가 필요하다면 포인터를" 선택하는 것이 일반적인 지침입니다.