다중 포인터

 

인프런 Rookiss님의 'Part1: C++ 프로그래밍 입문' 강의를 기반으로 정리한 필기입니다. 
😎[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 강의 들으러 가기!

 

 


 

포인터를 사용 -  원본 데이터 접근 후  수정

 

void SetNumber(int* a)
{
    *a = 1;
}

 

int main()
{
    int a = 0;
    SetNumber(&a);//주소값을 넘긴다.
    cout << a << endl;
}

위의 코드를 실행하면

1

이 출력된다.


 

 

원본 데이터가 수정이 되지 않는 경우 

 

void SetMessage(const char* b)
{
    b = "Bye";
}

 

int main()
{
    // .rdata  Hello주소 [H][e][l][l][o][\0]
    // .rdata  Bye주소 [B][y][e][\0]
    // msg[ Hello 주소 ] << 8바이트(64비트 프로그램 기준)
    const char* msg = "Hello"
    
    // [매개변수][RET][지역변수(msg(Hello주소))] [매개변수(a(Hello주소))][RET][지역변수]
    SetMessage(msg);
    cout << msg << endl; // Hello? Bye?
}

위의 코드를 실행하면

Hello

가 출력된다.

 

SetMessage(msg)를 실행하면 아래와 같다.

[매개변수][RET][지역변수(msg(Hello주소))] [매개변수(a(Hello주소))][RET][지역변수]

                                                                      [매개변수(b(Bye주소))][RET][지역변수]

종료

 

void SetMessage(const char* b) 내에서 매개변수 주소만 바뀔 뿐 원본에 영향을 주지 않는다. 


 

 

이중 포인터

 

void SetMessage(const char** b)
{
    *b = "Bye";
}

 

int main()
{
	const char* msg = "Hello";

    // 주소2 [ ] << 1바이트           // .rdata  Hello주소 [H][e][l][l][o][\0]
    // 주소1[ 주소2  ] << 8바이트      // msg[ Hello주소 ] << 8바이트
    // pp[ 주소1] << 8바이트          // pp[ &msg ] << 8바이트
    const char** pp = &msg;

    // [매개변수][RET][지역변수(msg(Hello주소))][매개변수(b(&msg 즉 msg의 주소)][RET][지역변수)]
    SetMessage(&msg);
    cout << msg << endl;
}

위의 코드를 실행하면

Bye

가 출력된다.

 

주소2 [ ] << 1바이트            (  .rdata  Hello주소 [H][e][l][l][o][\0] )
주소1[ 주소2  ] << 8바이트  (  msg[ Hello주소 ] << 8바이트      )
pp[ 주소1] << 8바이트         (  pp[ &msg ] << 8바이트               )

 

const char** pp = &msg;

 


 

 

다중 포인터 사용 Tip

 

다중 포인터 
-  그냥 양파까기라고 생각하면 된다
-  const char** pp2;  오른쪽부터 왼쪽 순서로 분석하자
-   * 을 하나씩 까면서 타고 간다고 생각하자

 


 

 

포인터 + 참조 사용

 

void SetMessage2(const char*& b)
{
    b = "Wow";
}

 

int main()
{
    const char* msg = "Hello";
    
    // [매개변수][RET][지역변수(msg(Hello주소))][매개변수(b(&msg 즉 msg의 주소)][RET][지역변수)]
    SetMessage2(msg);
    cout << msg << endl;
}

위의 코드를 실행하면

Wow

가 출력된다.

 

[매개변수][RET][지역변수(msg(Hello주소))]  [매개변수(b(&msg 즉 msg의 주소)][RET][지역변수)]
SetMessage2(msg);

 

 

※ 참조와 포인터는 내부적으로는(=어셈블리 코드 관점에서는) 똑같다.

 

 


 

 

전체 코드

 

더보기
#include <iostream>
using namespace std;

void SetNumber(int* a)
{
    *a = 1;
}

void SetMessage(const char* b)
{
    b = "Bye";
}

void SetMessage(const char** b)
{
    *b = "Bye";
}

void SetMessage2(const char*& b)
{
    b = "Wow";
}

int main()
{
    int a = 0;
    SetNumber(&a);
    cout << a << endl;

    // .rdata Hello주소 [H][e][l][l][o][\0]
    // .rdata Bye주소 [B][y][e][\0]
    // msg[ Hello 주소 ] << 8바이트
    const char* msg = "Hello";
    
    // [매개변수][RET][지역변수(msg(Hello주소))][매개변수(a(Hello주소))][RET][지역변수]
    SetMessage(msg);
    cout << msg << endl; // Hello? Bye?

    // 주소2 [ ] << 1바이트
    // 주소1[ 주소2  ] << 8바이트
    // pp[ 주소1] << 8바이트
    

    const char** pp = &msg;

    // [매개변수][RET][지역변수(msg(Hello주소))][매개변수(b(&msg 즉 msg의 주소)][RET][지역변수)]
    SetMessage(&msg);
    cout << msg << endl;

    // 다중 포인터 
    // 그냥 양파까기라고 생각하면 된다
    // const char** pp2;  오른쪽부터 왼쪽 순서로 분석하자
    // * 을 하나씩 까면서 타고 간다고 생각하자
    // 
    // [매개변수][RET][지역변수(msg(Hello주소))][매개변수(b(&msg 즉 msg의 주소)][RET][지역변수)]
    SetMessage2(msg);
    cout << msg << endl;

    return 0;
}

 

 

실행화면