티스토리 뷰

안녕하세요 쫑쫑블로그입니다.

오늘 배워 볼 내용은 포인터의 개념입니다.

포인터는 아마 C언어를 배우신 분 가장 어렵다고 말하는!!개념에 손꼽힙니다.

하지만 개념만 잘 잡는다면! 해결될 문제이니 천천히 읽으시면 됩니다.

 

먼저 포인터를 배우기 전에 변수의 주소 개념을 알고 있어야 합니다.

각 변수는 보이지는 않지만 메모리 주소가 있습니다. 지금까지 a = 4; 라고 했다면

실제로는 메모리의 주소값 1004라는 a값을 저장하라고 컴퓨터에게 지시를 한 것입니다.

조금은 이해되셨나요? 이제 예시를 보여드리겠습니다.

 

메모리의 주소 값이 100부터 시작한다고 가정될 때 int a, b; 라고 선언하겠습니다.

이 경우 차례대로 주소 값 100에는 a이 저장되며 주소 값 104에는 b가 저장됩니다.

 

여기서 질문!

왜 주소값은 4씩 움직일까요?

int4바이트이기 때문에 배열의 주소 값은 4씩 커지게 되는 것입니다.

이제 변수 a,b 에 값을 넣어보겠습니다.

a = 4; b = 3;이라고 선언했습니다.

현재 메모리 상에 주소 값 100에는 a가 저장되어 있었습니다.

이 경우 a=4;라고 선언해준다면

메모리 주소 값 100에는 a가 아닌 4가 저장됩니다..

 

처음에는 하나의 보관 장소라고 생각하시면 이해가 조금은 편할 것이라 생각됩니다.

이제 주소 값을 출력하는 방식을 설명 드리겠습니다.

&이렇게 생긴 기호는 처음 보시는 것이 아니라고 확신합니다. 어디서 봤을까요?

 

혹시 scanf의 선언 방법에서 값을 넣어줄 변수 앞에 &을 선언해주었던 것 기억나시나요?

&엠퍼사인이라고 불리며 이 뜻은 이 변수의 주소 값을 알려줘입니다.

따라서 &을 정의하자면 변수의 주소를 나타내는 연산자입니다.

 

scanf에 &이 필요한 이유를 이제는 깨닫게 되셨나요?

쉽게 말해 scanf는 변수의 입력을 받기위해서 변수의 주소 값이 필요했기 때문에

변수의 주소 값을 가져 왔다고 생각하시면 됩니다.

 

이제 포인터를 정의해드리겠습니다.

포인터는 다른 변수의 주소를 저장하는 변수입니다.

 

포인터와 일반 변수의 차이점

일반변수는 임의의 값을 저장하며 포인터는 메모리 상에서의 주소를 저장합니다.

즉 일반변수는 주소 값을 저장하는 것이 불가능하기 때문에 쓰는 것이라고 생각하시면 됩니다.

 

포인터 변수의 정의

먼저 선언 방식은 int *a; 입니다.

자료의 형식을 써주고 변수이름 앞에 *을 선언해주시면

컴퓨터에서 이 변수는 포인터구나 라고 인식할 수 있게 됩니다.

*의 쓰임새를 좀 더 자세하게 설명하기위해 간단한 예제를 보여드리겠습니다.

int a, num, *ptr;

num = 4;

ptr = #

a = *ptr;

printf(“%d”, a);

여기서 문제)이 예제에서 *ptr 은 무슨 뜻일까요?

이는 ptr이 가지고 있던 주소 값에 원래 num값을 의미합니다.

*ptr == num 입니다. *ptrnum의 값이 같습니다

 

*의 정의

*을 정의하자면 ptr이 가르키고 있던 대상을 나타내는 연산자 입니다.

*& 두가지는 꼭꼭 기본 개념이니 알고 계셔야 합니다.

왜냐하면 포인터라는 개념을 후에 깊게 적용하기 위해서는 필수로 중요한 정보이기 때문입니다.

이제 기본개념을 정리하는 예제를 알려드리겠습니다.

Int a = 3;

Int *num1;

num1 = &a;

printf(“정수 a의 값 : %d\n”, a); // 3출력

printf(“정수 a의 주소 값 : %d\n”, &a); // a의 주소값 출력(시도 때 마다 다름)

printf(“정수 a의 본래 값 : %d\n, a) // 3출력

printf(“num1이 가르키는 값 : %d\n, *num1); // 3출력

printf(“num1의 주소 값 : %d\n, num1); // a의 주소값과 똑 같은 값 출력

 

이 예제를 이해하신다면 포인터의 기초에 대해 완벽하게 이해하신 겁니다! ㅎㅎ

이제 다른 예제를 풀어보도록 하겠습니다.

포인터 개념을 이해했다면 조금 더 심화 과정의 문제인데요!

포인터의 포인터를 넣어 헷갈리게 만든 예제입니다. 답은 써놓았습니다!

 

#include

int main() {

 

int a = 10;

int *ptr;

ptr = &a;

int **ptr_ptr; //*ptr를 가르키는 포인터를 가르키는 포인터 **가 두번 쓰인다.

ptr_ptr = &ptr;

 

printf("a = %d\n", a);

printf("&a = %d\n", &a);

printf("ptr = %d\n", ptr);

printf("&ptr = %d\n", &ptr);

printf("*ptr_ptr = %d\n", *ptr_ptr);

// ptr_ptr이 가르키고 있는 변수는 ptr이기 때문에 ptr의 주소값이 나온다

printf("**ptr_ptr = %d\n", **ptr_ptr)

// *ptr_ptr = ptr = *(*ptr_ptr) = *ptr(a의 값이 저장되어있음) = a

 

마지막으로 총 정리 해드리자면

 

1. 포인터 변수 선언시 *을 붙힌다.

2. &가 붙은 것들은 변수의 주소를 뜻한다.

3. 포인터 변수를 선언 후 *을 붙히면 시작주소에서 포인터 변수의 형 크기만큼의 데이터를 불러온다.

4. 포인터 변수를 선언 후 &을 붙히면 포인터 변수의 시작주소를 불러온다.

 

지금까지 쫑쫑블로그 이었습니다. 다음은 배열과 포인터의 관계로 오겠습니다!

궁금하신 점이나 다른 질문은 댓글로 해주세요!

공감과 댓글은 언제나 힘이 됩니다!