대학교나 인터넷이나 어떤 C 강의를 들어도 늘 "C 언어의 꽃, Pointer" 라고 한다.
꽃이 아니라 fuck...
여튼 처음에는 어려웠으나 한번만 이해하면 겁나 꿀인 pointer
어디 한번 찢어보자.
기타 응용까지 하면 한페이지에 담기에 너무 많으니 개념만 확실히 짚고 가자.
Pointer(포인터), 늬 누구니?
"메모리 주소를 저장하는 변수로, 메모리 내의 데이터 위치를 참조하고 접근하는 데 사용된다."
Pointer의 핵심 point는 "메모리 주소를 저장하는 변수".
왜 핵심이냐면,
처음 포인터라는 단어를 봤을 때는 pointer? 뭐 가리키는 느낌인데? 했다.
뭐 틀린 말도 아니고, 나중에 가리키는 걸로 예시를 들거지만 !
"메모리 주소를 저장하는 변수" 로 이해하고 들어가자.
바로 예시를 보자.
int num = 10;
int * ptr = &num
위 의미는 num이라는 int형 변수에 10이라는 값을 넣고,
ptr 이란 포인터 변수에 변수 num의 주소값을 저장한다.
하나하나 봐보자.
1) 포인터 변수를 선언할 때 : 자료형 + *
수업만 대충 들었을 때는 o.o "아~ 변수 앞에 별표만 붙여주면 되는구나~" 라고 단순히 받아들였다.
코드 짜는데는 크게 상관없지만 이해하는데 있어서는 제대로 짚고 넘어가야된다.
포커스는 변수 앞에 별표가 아니라, ( * + 변수명)
자료형 뒤의 별표다. ( 자료형 + * )
그럼,
[ int * ptr; ] 포인터 변수 선언의 의미는
" int 타입의 포인터 + 변수 ptr "
즉, int 형의 타입의 변수의 주소를 저장할 수 있는 포인터 변수.
아까 위에 뭐라고했나, "메모리 주소를 저장하는 변수"
기억.
2) 변수의 주소값을 가져올 때 : & + 변수명
&기호는 변수의 주소값을 참조한다.
즉, &num 은 num 변수의 주소값, 현재 메모리에 저장된 위치를 나타낸다.
그럼 1) + 2)를 조합하자.
int * ptr = &num
int 타입의 메모리를 저장하는 포인터 변수 ptr 에 num의 주소값을 저장한다.
그림으로 나타내면 아래와 같다.
( 주소는 임의로 부여, 변수 선언마다 바뀐다. )
ptr 포인터형 변수는 num이라는 변수의 address(주소값)을 저장한다.
실제 ptr 포이터 변수와 num 변수의 각 값을 봐보자.
#include <stdio.h>
int main(void){
int num = 10;
int * ptr = #
// 변수 num의 주소값과 저장된 값.
printf("변수 num\n");
printf("Address : %p, Value : %d \n\n", &num, num);
// 변수 ptr의 주소값과 저장된 값.
printf("변수 ptr\n");
printf("Address : %p, Value : %p \n\n", &ptr, ptr);
}
자, 여기까지 이해됐으면 사실 pointer를 이용하려는 이유는
Pointer 변수를 활용하여 Pointer 변수에 저장된 주소값에 해당하는 변수의 값에 접근하기 위해서이다.
어떻게 하느냐 !
별표 * 의 의미는 손가락이라고 생각하고, 그 손가락이 가리키는 값이라 생각하자. ( 변수 선언할 때 제외.)
그럼 ( * ptr ) 이 의미하는 바는 ??
"ptr 의 손가락이 가리키고 있는 값"
그래서 ptr이 어디 가리키고 있는데?
"ptr에 저장된 주소에 저장된 Value"
즉, 위 예시로는 num의 value이다. ( 10 )
ㅋㅋㅋㅋㅋㅋ혼자 난리.
뜬금없지만 만약 그릇 위에 케이크가 담겨져있다 하자.
그럼 그릇 = 주소, 케이크 = 값이 될 것이다.
나는 저 그릇을 가리켰는데 사람들은 케이크를 볼 것이다.
정확한 예시는 아니지만 그런 뜻 ㅎㅋ
코드를 먼저 보여주면 이해가 쉽지만 일부러 이렇게 했다.
텍스트로 봐도 이해가 되어야지 코드에서는 더 쉽다. ( 물론 대학교 필기 시험을 더 잘보기 위한 )
#include <stdio.h>
int main(void){
int num = 10;
int * ptr = #
printf("변수 num\n");
printf("Address : %p, Value : %d \n\n", &num, num);
printf("변수 ptr\n");
printf("*ptr : %d, ptr : %p\n\n", *ptr , ptr);
}
자 그럼, 예시 문제를 내본다.
int num = 10;
int * ptr = &num
위와 같이 선언되었을 때 정답인 것을 모두 골라보시오.
1. num == ptr
2. num == *ptr
3. ptr == &num
4. * ptr == &num
정답은 ??
확인해보자.
1. num == ptr
위 상황에서 ptr은 뭐라고? int 형타입의 변수의 주소를 저장하는 포인터 변수.
즉 ptr에는 변수의 주소가 저장되어있다.
근데 num 은 변수 값을 나타내고 ptr 은 num으 주소 값을 나타낸다.
답 : X
2. num == *ptr
아까 * 는 뭐? ptr의 손가락이 가리키고 있는 값.
근데 뭘 가리킨다 ? ptr에 저장되어있는 주소에 저장된 value !
답 : O
3. ptr == &num
ptr은 num의 주소가 저장되어있고, &num은 num의 주소값이라 했다.
답 : O
4. *ptr == &num
행여 ==을 대입연산으로 착각하지는 않았는가. 없겠지
*ptr 은 위에서 num의 값이라 했다.
&num은 num의 주소값.
답 : X
이렇게 생각할 수 있다.
어 ?
그럼 포인터 변수에 바로 정수를 넣어 주소값을 전달할 수 있나?
답은 안된다 이다.
int * ptr = 153453
위와 같이 대입하면
대입 연산자 뒤에 나온 숫자가 메모리 주소값인지 그냥 값인지 알 수 없기 때문에 의도된 대로 정상동작할 수 없다.
그럼 포인터를 왜 사용하냐?
프로그래밍에서 데이터의 효율적인 관리와 조작을 가능하게 하기 위함이다.
동적 메모리 할당, 배열과 문자열, 함수에 인자 전달, 동적 데이터 구조와 같은 데 활용되는데 이는 한페이지에 다루기 어려우니 추후 작성하게 되면 다루겠다.
오늘은 단순한 포인터 변수에 대해 알아보았다.
'컴터 > C, C++' 카테고리의 다른 글
C++ 문자열 숫자 곱하기 (0) | 2023.06.16 |
---|---|
c++ at(-1), [-1] 뭐는 되고? 왜 다르지? (0) | 2023.02.25 |
c++ string :: npos 는 -1 ? (0) | 2023.02.23 |