본문 바로가기
C++/기초

C++ 기초 : 포인터

글: 시플마 2024. 3. 29.

주소를 저장하는 변수를 포인터 변수라고 합니다.

 

아래 코드를 보면

 

int형 포인터 변수 'pInt'을 선언하고 nullptr을 대입했습니다.

nullptr은 아무것도 대입하지 않는 것과 같은 의미죠.

 

 

이번에는 int형 변수 'i'를 선언하고 100을 대입했습니다.

 

그리고 포인터 변수 pInt에 &i를 대입했습니다.

변수 앞에 &를 붙이면 해당 변수의 주솟값을 나타냅니다.

즉 pInt에 변수 i의 주솟값을 넣었다고 볼 수 있습니다.

 

 

그럼 여기서 주솟값은 무엇일까요?

메모리에는 각 자리마다 어떤 값이 들어있을 겁니다.

비어있는 경우도 있겠죠.

 

그 값에 접근하려면 해당 값이 있는

메모리의 주소를 찾아가 접근하는 겁니다.

 

비어 있는 자리에 값을 넣을 때도 마찬가지로

주소를 찾아가 빈 자리에 값을 넣을 겁니다.

 

 

주솟값이 1000번지인 곳과 10005번지인 곳 사이에는 

얼마큼의 공간이 있는 걸까요? 

1001번지, 1002번지, 1003번지, 1004번지가 있을 겁니다.

그리고 각 번지의 크기는 Byte입니다.

 

그럼 1Byte는 8Bit로 나눌 수 있는데 각 Bit마다 

주소를 부여할 수 있을까요? 이를테면

1001.5번지, 1001.6번지처럼 말이죠.

 

주소는 실수가 아닌 정수로 표현하기 때문에 

소수점 단위로 주소를 부여하는 것이 불가능합니다.

 


 

 

아래 코드를 봅시다.

 

(*pInt) = 10;라는 코드가 추가되었습니다.

pInt는 포인터 변수입니다. 여기에 *을 붙였네요.

이는 "포인터 변수 pInt가 저장하고 있는 주솟값으로

가라."라는 의미입니다. 그곳에 간 후 10을 대입하라는 것입니다.

 

pInt는 변수 i의 주솟값을 저장하고 있으므로

변수 i로 가서 10을 대입하라는 것이죠.

 

 

실행 결과를 볼까요?

 

pInt에는 0x00aff74c라는 값이 저장되어 있습니다.

변수 i의 주솟값이겠네요.

이후 해당 주소로 가 10을 대입합니다.

변수 i의 값이 10으로 바뀐 것을 확인할 수 있습니다.

 

 

이 과정을 그림으로 나타내면 아래와 같습니다.

 

 

 


 

 

 

위에서 선언한 포인터 변수 pInt는 int형 포인터 변수입니다.

왜 int형으로 선언했을까요?

int형 변수의 주솟값을 담을 것이고,

필요하면 직접 접근해서 값도 건드릴 것이기 때문이죠.

 

별거 아닌 거 같지만 포인터 변수에 있어서 

상당히 중요한 내용입니다.

 

 

조금 더 깊게 생각해 봅시다.

아래 코드를 보시죠.

 

float형 변수 f를 선언하고 3을 대입했습니다.

그리고 f의 주솟값을 int형으로 선언된

포인터 변수 pInt에 저장했습니다.

(이런 시도는 문법 오류로 인식하지만

&f 앞에 (int*)를 붙여 강제로 형변환하여 진행했습니다.)

 

이후 pInt에 저장된 주솟값으로 이동하여

그곳에 있는 값을 변수 i에 저장합니다.

 

 

실행 결과를 보겠습니다.

 

변수 i에 이상한 값이 대입된 것을 확인할 수 있습니다.

어떻게 된 걸까요?

 

이유는 주솟값을 담은 포인터 변수(정수)와

그 주소에 있는 변수(실수)의 형태가 다르기 때문입니다.

 

특히 정수와 실수는 컴퓨터에서 표현 방식 자체가 다르죠.

정수는 이진수로 딱 맞게 표현이 가능하지만

실수는 그것이 안되기 때문에 근삿값을 찾아 표현하는

부동소수점 방식을 사용합니다.

그래서 정수 3과 실수 3.0은 다르다는 것이죠.

 

일단 23번째 줄까지는 문제가 없습니다.

어차피 실수형 변수 f도 주솟값은 정수이기 때문입니다.

하단 '로컬' 창을 보면 포인터 변수 pInt에 변수 f의 주솟값이 

담겨있는 것을 볼 수 있습니다.

 

문제는 25번째 줄에서 발생합니다.

pInt에 저장된 주솟값을 직접 찾아가

그곳에 있는 값을 변수 i에 대입하라는 코드입니다.

 

pInt에 저장된 주솟값을 찾아갔더니

3을 실수로 표현하기 위한 어떤 값이 들어가 있는 것입니다.

하지만 이러나저러나 4Byte인 int형 포인터 변수 pInt는 

딱 4Byte만큼만 값을 읽어와서 변수 i에 대입한 것이죠.

 

만약 char형 변수였어도

1Byte 크기의 char형 변수를

4Byte만큼 읽게 되면 문제가 발생하겠죠.

 

아무튼 이런 이유로 변수 i에는 3이 아닌,

3을 실수로 표현하기 위한 어떤 수를 저장하게 된 것입니다.

 

 

이를 그림으로 표현하면 아래와 같습니다.

 

 

 

 


 

 

 

 

위 내용을 보면

자료형은 어떤 값을 해석하는데 상당히 

중요한 역할을 하고 있음을 알 수 있습니다.

 

이는 해당 글에서도 다룬 적이 있습니다.

https://cpp-mastery.tistory.com/3

 

C++ 기초 : 정수형 자료형

unsigned를 붙인 char형 변수가 나타낼 수 있는 수의 범위는 0 ~ 255 입니다. unsigned를 붙인 char형 변수가 나타낼 수 있는 수는 256가지입니다. unsigned를 붙이지 않은 경우 음수까지 표현해야 합니다. 음

cpp-mastery.tistory.com

 

char형 변수에 255를 대입하면 -1로 인식하고 

unsigned char형 변수에 255를 대입하면 255로 인식하는

이유를 살펴보았었죠.

 

같은 값이라고 생각해도 자료형이

정수냐, 실수냐, signed냐 unsigned냐에 따라

다르게 해석되므로 주의할 필요가 있습니다.

 

 

포인터 변수에서 자료형이 의미하는 것은

해당 포인터 변수에게 전달되는 주소를

해석하는 단위라고도 볼 수 있겠네요.

 

 

 

 

강의 출처 : https://www.youtube.com/watch?v=PFc4g8mxOiI&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&pp=iAQB

 


 

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

C++ 기초 : 포인터 문제 풀이와 해답  (0) 2024.03.30
C++ 기초 : 포인터 배열  (0) 2024.03.30
C++ 기초 : 운영체제  (0) 2024.03.29
C++ 기초 : 정적 변수와 외부 변수  (0) 2024.03.29
C++ 기초 : 분할 구현의 문제점  (0) 2024.03.22