Data is ___ !
Published 2025. 6. 4. 15:11
[C++] 포인터 Programming/C++

포인터 개념 

포인터 변수란 ? 

주소를 저장하는 변수를 말한다. 일반적으로 변수를 만들 때 어느 정도의 크기를 가지고 있는지, 무슨 용도로 쓰일 것인지를 나타내는 자료형을 선언한다. 이때 `자료형* 변수명`처럼 자료형 뒤에 *가 붙으면 이거는 "주소명을 저장하는 포인터 변수인데, 주소가 가르키고 있는 곳을 앞에서 선언한 자료형으로 본다"는 의미이다. 

예를 들어 ` char* pChar = nullptr;`는 pChar 변수에 주소를 넣어주면 그 주소로 갔을 때 1byte 정수로 보겠다는 것이다. 여기서 진짜 어떤 형태로 되어있는지는 중요하지 않음! 반면 ` short* pShort = nullptr;`는 pShort 변수에 주소를 넣어주면 그 주소로 갔을 때 2byte 정수로 보겠다는 것이다. 만약 여기서 `int*`로 선언한다면 주소를 읽을 때 4byte 단위로 읽게 되어 크기 및 해석 문제가 발생한다. 

 

포인터 변수의 자체 크기는 ? 

포인터 변수는 int 자료형을 가진 변수가 아니라 주소를 저장하는 변수이다. 그리고 주소값을 넣어주면 해당 주소로 갔을 때 int로 "해석"하겠다는 의미를 가진 변수이다. 따라서 주소를 저장한다는 용도가 같고 크기도 같다. 

이때 솔루션 플랫폼이 32bit이면 포인터 변수의 크기는 4byte이고 64bit이면 8byte 크기를 가진다. 특히 32bit에서는 2^32(약 42억)개까지 주소를 저장할 수 있고 약 4GB를 나타낸다. OS의 한계 때문에 RAM을 4GB 이상 꽂아도 의미가 없다. 반면 64bit는 2^64개까지 주소를 저장할 수 있고, 4GB를 42억개 꽂을 수 있는 크기이다. `sizeof(int*);` 또는 `sizeof(pInt);`로 크기를 확인할 수 있다. 

 

 

주소란 ? 

실제 기계어로 번역될 때에는 내가 작성한 문법을 수행하기 위해서 컴파일된 코드들이 특정 주소 위치에다가 값을 넣도록 명령어가 만들어진다. (메모리의 위치를 지칭하기 위해서) 이러한 주소 개념을 C++ 문법에서도 쓸 수 있다. 

주소를 알면 포인터 변수를 이용해서 특정 변수 값에 접근할 수도 있고 값을 수정할 수도 있다. 

주소의 단위는 byte로 "주소의 차이값 == byte" 수이다. 

 

주소의 이동은 ? 

주소를 표현하는 포인터 변수는 정수형 표현 방식을 따르고 있다. 즉, 주소 한 칸 당 1byte 크기와 같다. 

하지만 아래 코드와 같이 pInt에 1을 더하면 실제값은 +1이 되는 것이 아니라 +4가 된다. 표현방식은 정수긴 한데 포인터의 연산은 정수의 연산을 따르지 않는다. 

다시 한번 말하지만 pInt는 "주소 변수"이다. 그냥 주소가 아니라 pInt에 저장된 주소값으로 갔을 때 메모리에 저장된 값들은 int 자료형으로 보는 주소이다. 따라서 이런 변수에 주소를 하나 증가시킨다는 것은 다음 int 위치로 가겠다는 것이다. 주소에 1을 더해주면 자료형 1단위 만큼 증가한다. 

특히 pInt는 `int*` 변수이기 때문에 주소가 가리키는 곳을 int로 해석한다. 따라서 주소값이 1증가한다는 것은 다음 int 위치로 접근하기 위해서 `sizeof(int*)` 단위만큼 증가하게 된다. 

 

 

 

 

 

 

 

 

포인터 동작 방식 

int main() 
{
    int i = 100;
    float f = 3.f;
    
    int* pInt = nullptr;  //포인터는 아무것도 가리키지 않는다. 0이 저장됨 
    int* pInt = &i;       //int형 포인터에 int형 변수 i의 주소값을 저장한다.
    int* pInt = (int*)&f; //int형 포인터에 float형 변수 f의 주소값을 저장한다.(잘못된 방법)
    
    i = *pInt;            //pInt에 저장된 주소로 접근한다.
    (*pInt) = 100;        //pInt에 저장된 주소로 접근해 직접 수정한다.

}

포인터 변수 선언

  • `[자료형]* [변수명] = &[주소값을 가져올 변수];`     
    • `[자료형]*` : 포인터 타입의 자료형을 나타내고, 주소를 나타내는 변수를 선언하는 것과 같다. 
    • ` &[주소값을 가져올 변수]` : 해당 변수의 주소값을 가져온다. 
    • pInt에 주소를 저장했을 때, 주소값에 해당하는 실제 메모리 공간을 int로 보겠다는 것 ( int형 포인터의 주소를 받는 pInt 변수에 int형 변수 i의 주소값을 가져와서 저장할거야) 
  • 포인터 변수 앞에 선언되는 자료형의 의미는 자기가 가르킬 데이터의 타입을 정해논 것이다. (해당 포인터 변수에게 전달된 주소를 "해석"하는 단위라고도 한다.) 때문에 pInt 포인터 변수로 접근할 때 i변수 사이즈와 타입에 맞춰서 접근할 수 있었던 것이다. 사이즈가 달라도 안되고, 자료형이 달라도 안된다. 왜냐 ? 이전 포스팅에서 '메모리 안에 데이터는 똑같은데 어떻게 해석하는지에 따라서 다르게 해석될 수 있다'고 한 적이 있다. 즉, 같은 1byte로 표현된 변수인데 비트값의 메모리는 바뀌지 않음에도 불구하고 음수까지 표현하는 방식으로 봤을 때는 -1로 보이기도 하고, 양수만 표현하는 방식으로 봤을 때는 255로 보이기도 한다. 메모리 안에 있는 값이 바뀐게 아니다. 해석을 달리했을 뿐이다. 이처럼 포인터도 똑같다!!! 실수 3.f라는 값은 정수 표현방식으로는 다른 수가 된다. 
  • 주소를 저장할 pInt 변수의 자료형은 i변수(int)와 똑같은 자료형을 선언해라 -> 왜 ? -> 나는 다시 그 주소로 갈 때 4byte 접근할 거거든. 그리고 i변수를 표현 방식으로 해석할거거든. 

 

주소 접근 

  • `[변수] = *[주소를 나타내는 변수]`
    • ` *[주소를 나타내는 변수]` : 변수에 저장된 주소값으로 접근하는 것  

=> 변수 앞에 &가 붙어있으면 주소값을 가져오는 것, *가 붙어있으면 주소값에 접근하는 것, 자료형 뒤에 *가 붙어있으면 해당 자료형을 가진 포인터 변수를 선언하는 것 

 

 

 

 

 

 

 

배열과 포인터

배열의 특징

1) 메모리가 연속적인 구조, 2) 배열의 이름은 배열의 시작 주소라는 특징을 갖고 있다. 

int iArray[10] = {};
*(iArray + 1) = 10; //iArray의 초기 값은 배열의 시작 주소인 0이고 이때 1칸 더해주면 4byte 만큼 더해진 주소에 접근한다. 그곳에 10을 저장한다. 
*(iArray + 0) = 0;  //iArray[0] = 10과 같은 코드가 된다.

 

 

포인터 문제

[1번]

short sArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* pI = (int*)sArray; 
int iData = *((short*)(pI + 2));  
printf("1번 문제 정답 : %d\n", iData);

 

[2번]

char cArr[2] = { 1, 1 };
short* pS = (short*)cArr; 
iData = *pS;
printf("2번 문제 정답 : %d\n", iData);

 

 

 

 

 

 

 

 

 

함수 간 포인터 활용

void Test_1(int a)
{
    a = 500;
}

void Test_2(int* a)
{
    *a = 500;
}

int main()
{
    int a = 100;
    Test_1(a); //a=500으로 바뀌지 않는다. 
    
    // a라는 변수가 Test() 함수 호출 이후에 500으로 바꼈으면 좋겠으면 ? 
    // a의 주소값을 전달하면 된다. 
    Test(&a) 
}

'Programming > C++' 카테고리의 다른 글

[C++] void  (0) 2025.06.27
[C++] const, const 포인터  (0) 2025.06.27
[C++] Visual Studio 단축키, 디버깅  (0) 2025.06.03
[C++] 분할구현  (0) 2025.06.03
[C++] 변수의 종류, 메모리 영역  (0) 2025.06.03
profile

Data is ___ !

@콩순이컴퓨터

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...