앞에서 잠깐 포인터가 무엇인지에 대해서는 알아봤다.
이제 프린터에 대해 심화학습을 해보자. 공부 및 자료참조는 코딩도장에서 했다.
"포인터는 주소"다.
포인터 변수에 저장되는 값은 (메모리 상에서 어떤 data를 가리키는) 주소값이다. 이 것을 항상 잘 생각하자.
정답은 cpu에따라 다르다. 32, 64bit 컴퓨터에서 각각 32bit / 64bit이다.
//아래와 같이 실행해보면 확인해볼 수 있다.
sizeof(포인터)
sizeof(자료형 *)
*은 포인터 변수를 만들어 줄 때도 사용했지만, 포인터 변수 앞에 *을 붙이면 "포인터 변수가 가리키는 주소값으로 가라"는 뜻이 된다. 따라서 아래와 같이 작성하면 '10'이 프린트 된다.
#include <stdio.h>
int main()
{
int *numPtr; // 포인터 변수 선언
int num1 = 10; // 정수형 변수를 선언하고 10 저장
numPtr = &num1; // num1의 메모리 주소를 포인터 변수에 저장
printf("%d\n", *numPtr); // 10: 역참조 연산자로 num1의 메모리 주소에 접근하여 값을 가져옴
}
아래의 사진처럼 생각하면 된다. 포인터를 선언할 때 사용한 *과 역참조를 하는 *를 구분지어 생각하는 편이 좋다.
자료형 마다 *을 붙여서 포인터를 만드는 이유는 아래와 같다. 즉, 어떤 자료형이냐에 따라 그 크기에 해당하는 만큼 주소에 접근하기 때문이다.
- 포인터는 상수를 가리킬 수 있다. 그럼, 포인터로 그 값에 접근해서 조회는 할 수 있지만 변경은 할 수 없는 상황인 것이다.
const int num1 = 10; // int형 상수 const int *numPtr; // int형 상수를 가리키는 포인터. int const *numPtr도 같음 numPtr = &num1; *numPtr = 20; // 컴파일 에러. num1이 상수이므로 역참조로 값을 변경할 수 없음
- 반면, 포인터 자체를 한 메모리 주소만 가리키게 상수처럼 설정할 수 있다. 다른 주소값 입력이 불가능하게 만드는 것이다.
int num1 = 10; // int형 변수 int num2 = 20; // int형 변수 int * const numPtr = &num1; // int형 포인터 상수 numPtr = &num2; // 컴파일 에러. 포인터(메모리 주소)를 변경할 수 없음
const 자료형을 가리키는 const 포인터도 만들 수 있지만, 굳이 쓸 일이 없을 것 같아서 적지 않았다.
다음 포스팅에서 포인터의 꽃(?)인 void포인터와 이중 포인터, 포인터 형 변환 등에 대해 알아보자.
내사랑귀염둥이 화이팅❤️ 잘하그있그만!!!! 좋아좋아 우리집 가장 화이팅!