C++ Pointer Reference

C++에서 포인터와 참조자는 매우 중요한 개념으로, 메모리와 데이터를 직접적으로 관리하고 접근할 수 있게 합니다. 여기서는 포인터의 기본 개념, 포인터 연산, 참조자, 동적 메모리 할당 등을 자세히 설명하겠습니다.

포인터

포인터의 기본 개념

포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 포인터는 특정 타입의 데이터를 가리킬 수 있도록 선언됩니다.

#include <iostream>

int main() {
    int var = 42;       // 정수 변수 선언
    int* ptr = &var;    // var의 주소를 저장하는 포인터 선언

    std::cout << "var의 값: " << var << std::endl;
    std::cout << "ptr이 가리키는 값: " << *ptr << std::endl;

    return 0;
}

위 예제에서 ptrvar의 메모리 주소를 저장하는 포인터입니다. *ptrptr이 가리키는 값을 참조합니다.

포인터 연산

포인터 연산은 포인터를 조작하는 방법을 제공합니다. 주요 연산은 다음과 같습니다:

  • & 연산자: 변수의 주소를 구합니다.
  • * 연산자: 포인터가 가리키는 주소의 값을 참조합니다.
  • 포인터 산술 연산: 포인터에 정수를 더하거나 빼서 메모리의 다른 위치를 가리키게 할 수 있습니다.
#include <iostream>

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int* ptr = arr; // 배열의 첫 번째 요소를 가리키는 포인터

    for (int i = 0; i < 5; ++i) {
        std::cout << "arr[" << i << "] = " << *(ptr + i) << std::endl;
    }

    return 0;
}

위 예제에서 ptr + iarr[i]와 동일합니다.

참조자

참조자는 다른 변수를 가리키는 별칭입니다. 참조자는 선언 시에 초기화되어야 하며, 이후 다른 변수를 참조할 수 없습니다.

#include <iostream>

int main() {
    int var = 42;
    int& ref = var; // var의 참조자 선언

    std::cout << "var의 값: " << var << std::endl;
    std::cout << "ref의 값: " << ref << std::endl;

    ref = 100; // 참조자를 통해 var의 값을 변경

    std::cout << "변경된 var의 값: " << var << std::endl;

    return 0;
}

위 예제에서 refvar의 참조자로, ref를 통해 var의 값을 변경할 수 있습니다.

동적 메모리 할당

동적 메모리 할당은 런타임에 메모리를 할당하는 방법입니다. C++에서는 newdelete 연산자를 사용하여 동적 메모리를 할당하고 해제할 수 있습니다.

#include <iostream>

int main() {
    // 정수형 메모리 동적 할당
    int* ptr = new int;
    *ptr = 42;
    std::cout << "동적으로 할당된 메모리의 값: " << *ptr << std::endl;

    // 메모리 해제
    delete ptr;

    // 정수 배열 메모리 동적 할당
    int* arr = new int[5];
    for (int i = 0; i < 5; ++i) {
        arr[i] = i * 10;
    }

    std::cout << "동적으로 할당된 배열의 값: ";
    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    // 배열 메모리 해제
    delete[] arr;

    return 0;
}

위 예제에서는 정수형 변수와 정수 배열을 동적으로 할당하고, 할당된 메모리를 delete 연산자를 사용하여 해제합니다.

포인터와 참조자를 사용한 함수

포인터와 참조자를 함수의 매개변수로 사용하면 함수가 호출된 곳에서 변수의 값을 변경할 수 있습니다.

포인터를 사용한 함수

#include <iostream>

void increment(int* ptr) {
    (*ptr)++;
}

int main() {
    int num = 10;
    increment(&num);
    std::cout << "포인터를 사용한 함수 호출 후 num의 값: " << num << std::endl;

    return 0;
}

참조자를 사용한 함수

#include <iostream>

void increment(int& ref) {
    ref++;
}

int main() {
    int num = 10;
    increment(num);
    std::cout << "참조자를 사용한 함수 호출 후 num의 값: " << num << std::endl;

    return 0;
}

위 두 예제에서 increment 함수는 포인터와 참조자를 사용하여 num의 값을 증가시킵니다.

예제 프로그램

아래는 포인터, 참조자, 동적 메모리 할당을 모두 사용하는 예제 프로그램입니다:

#include <iostream>

// 포인터를 사용한 함수
void incrementPtr(int* ptr) {
    (*ptr)++;
}

// 참조자를 사용한 함수
void incrementRef(int& ref) {
    ref++;
}

int main() {
    int num = 10;

    std::cout << "초기 num의 값: " << num << std::endl;

    // 포인터를 사용하여 num의 값을 증가
    incrementPtr(&num);
    std::cout << "포인터를 사용한 함수 호출 후 num의 값: " << num << std::endl;

    // 참조자를 사용하여 num의 값을 증가
    incrementRef(num);
    std::cout << "참조자를 사용한 함수 호출 후 num의 값: " << num << std::endl;

    // 동적 메모리 할당
    int* dynamicNum = new int(20);
    std::cout << "동적으로 할당된 메모리의 초기 값: " << *dynamicNum << std::endl;

    // 동적 메모리 해제
    delete dynamicNum;

    return 0;
}

이 프로그램은 포인터와 참조자를 사용한 함수 호출 및 동적 메모리 할당의 예를 보여줍니다. 포인터와 참조자의 개념을 이해하고, 동적 메모리 관리를 통해 효율적인 프로그램을 작성하는 데 도움이 될 것입니다.

Leave a Reply

Your email address will not be published. Required fields are marked *