[C++] 포인터 기초

WestCoast·2021년 12월 30일
0

C, C++

목록 보기
2/12

포인터

  1. '포인터 = 주소' 라고 생각하자.
    기존 변수들(int, float 등)이 값을 저장하는 바구니라면, 포인터는 주소를 저장하는 바구니다.

  2. 기본적인 형식

  int number = 1;
  // ptr은 number의 주소를 가리키게 된다.
  int* ptr = &number;
  // ※아래 주소값들은 컴퓨터 환경마다, 실행할 때마다 달라질 수 있다.
  // ptr의 주소 = 0x008FFE64, ptr의 값(number의 주소) = 008ffe70
  // number의 주소 = 0x008FFE70, number의 값 = 1

  1. * : 사용 시점에 따라서 구분해서 기억하자.
    변수 선언 시 -> 주소를 저장하는 바구니다!
    사용할 시 -> 포탈 타고 순간이동!
    int* ptr = &number;
    // value1에 ptr이 가리키고 있는(number=1) 변수의 값을 넣어라!
    int value1 = *ptr;	
    // number의 값을 2로 바꿔라!
	*ptr = 2;	

함수에서 원본 데이터를 수정하려면?

  // [ 매개변수(hp의 주소) ][ RET ][ 지역변수 ]
  // void SetHp(int* hp) --> void SetHP(hp의 주소)
  void SetHp(int* hp) 
  {
      // *hp --> hp의 주소로 이동해라.(순간이동)
      *hp = 100;
  }

  int main()
  {
      int hp = 10;
      cout << hp << endl;	// hp = 10
      SetHp(&hp);
      cout << hp << endl;	// hp = 100
  }

알고 가자

  1. 포인터라는 바구니는 4byte or 8byte 고정 크기이다.
    (운영체제가 32bit인지 64bit인지에 따라 다르다.)
    고정크기인 이유? -> 결국은 주소를 담고 있기 때문.

  2. 그럼 int* 처럼 포인터가 어떤 자료형을 가리키는지 명시해줄 필요가 없는거 아닌가?

    • TYPE을 명시해주지 않으면 해당 포인터가 무엇을 가리키고 있는지 명확히 알기(분석하기)가 어렵다.
    • 몇 바이트 크기의 자료형인지에 따라서 해석을 다르게 할 수 있기 때문.
  3. 주의) 타입의 불일치
    number 는 int 형(4byte 정수)인데, __int64 형(8byte 정수)로 캐스팅 한다면?
    다른 메모리 주소를 침범하여 값을 덮어쓰게 된다. -> 데이터가 오염된다.

    __int64* ptr2 = (__int64*)&number;
    // AABB CCDDEEFF -> AABB가 다른 메모리 주소에 쓰여진다.
    *ptr2 = 0xAABBCCDDEEFF;     

__int64* ptr2 = (__int64*)&number; 에 브레이크 포인트를 걸고 디버깅한 모습.

  • number 의 주소 = 0x0096FBA4
  • number 의 값 = 1
  • ptr2가 가리키고 있는 number의 값 = -368934...
    (number의 원래 자료형인 int가 아닌 __int64로 캐스팅 했기 때문에 비정상적인 값을 보여주고 있다.)

*ptr2 = 0xAABBCCDDEEFF; 까지 실행하고 디버깅한 모습.

  • number 의 주소 = 0x0096FBA4
  • number 의 값 = 0xccddeeff
  • ptr2가 가리키고 있는 number의 값 = 1877235...
    (number의 원래 자료형인 int가 아닌 __int64로 캐스팅 했기 때문에 비정상적인 값을 보여주고 있다.)
profile
게임... 만들지 않겠는가..

0개의 댓글