Layer 7 06 과제 -포인터 보고서

2019. 4. 7. 16:57layer7

오늘은 'c언어의 꽃'이라고 불리는
포인터에 대해서 배워보겠습니다.

먼저 포인터를 알기 전 
기존의 우리가 쓰던 변수를 알아야 합니다.


# 변수란?

- 데이터를 저장하는 공간을 말합니다.

보통 우리들은 '변수' 
'값을 담는 상자'라고  표현을 합니다.

기존에 저희들은 저 '변수'라는 상자에 
정수(short, int), 실수(float, double),
문자(char), 문자열(string), 
논리형(boolean) 등의 데이터(값)를 넣었습니다.
 
그렇다면 포인터란 뭘까요??


# 포인터란?

출처: NAVER 지식백과 -포인터의 사전적 의미-

 

설명이 되게 어렵게 되어있네요...... ㅠㅠ


먼저, 포인터는 변수입니다.
포인터는 지금까지 우리가 써왔던 
변수와 크게 다르지 않습니다.
그렇다면 어떤 점이 다르기에 
'포인터'라고 부르는 것일까요??


컴퓨터에는 메모리(Ram)라고 불리는 
공간이 있습니다.

우리가 위와 같이 변수를 선언하면 메모리라는 부분에 수가 상주하게 됩니다.

그리고 그 공간에는 모두 주소가 
부여되어 있습니다. 마치 '아파트 호수'처럼 말이죠.

사진 출처 -유키 No 블로그-: http://yukinoh.tistory.com/164

 

평소에 "나는 000동 000호에 살아"

이런 식으로 집으로 놀러 오는 지인에게
한 번쯤은 자신의 집 주소를 
설명해주셨을 겁니다.

이러한 호수는 그 많은 아파트 안의 집들
중 정확히 집의 위치를 알 수 있게 합니다.

이와 같이 컴퓨터에서도 
변수라는 친구가 있는 위치가 어딘지
컴퓨터가 쉽게  알기 위해 사용됩니다.

 

# 변수의 주소 확인하기


# %p는 뭘까요?

%p는 변수의 주소를 헥사(16진수)로 표현
할 때 사용하는 '포맷 문자열 서식'입니다.


컴퓨터 안에서 쓰는 주소이다 보니 16진수를 사용하여 0x1000, 0x1004...  같은 
수치로 표현하는 경우가 많습니다.

 

실행 결과



# 포인터 본론

포인터는  이러한 주소를 저장하는 
특수한 변수입니다.

※간혹 포인터라는 말 자체가 주소라는 의미로 사용 될 때도 있는데요.

   그거는 패스....

이 구문에 따른 포인터의 선언은 
다음과 같습니다.

ex) 포인터 pa를 선언합니다.

     int *pa;

 

위문장은 
int형 변수 주소를 저장할 수 있는
포인터 pa를 선언한 것입니다. 
이를 "int형 포인터 Pa"라고 부르기도 합니다.

설명을 용이하게 하기 위해서 변수의 이름을 'a',
    포인터 변수의 이름을 'pa'라고 하겠습니다.

 

# 포인터를 초기화 하는 방법 

포인터에 변수의 주소를 넣을 수 있는 
방법은 2가지가 있습니다.

\

위와 같이 변수 생성 후 

포인터 변수에 변수의 주소를 대입해주는 방법.

변수를 만들고,

포인터 변수를 만든 후

후에 포인터 변수에 변수의 주소를 대입해줍니다. 


그렇게 하면 아래의 '포인터와 변수 도식화'처럼
포인터 pa 변수 a의 주소가  저장됩니다.

그 결과, 포인터 pa의 값은 
변수 a의 주소(&a)와 같아집니다


그 결과 아래와 같이 볼 수도 있을 것입니다.

변수와 포인터 사이에 
''관계"가 만들어졌다.

 이러한 관계를 일컬어

pa가 변수 a를 가리킨다.

라고 부르기도 하며,  이를 

pa(의 값)가 변수 a(의 위치) 가리키게 되었다.

위와 같이 이해하면 좋을 것 같습니다.



그렇다면 포인터가 할 수 있는 일은
변수의 주소를 저장하는 일 밖에 없을까요?

- 당연히 아닙니다.


# 포인터 활용 

포인터 변수에 주솟값이 저장되면
그 포인터를 통해 원래 변수의 값을
역추적하고 변조하는 것이 가능해집니다.

포인터를 통해 변수의 값을 역추적할 때에는
앞에 "*"라는 연산자를 붙입니다.
 * 연산자는 '간접 참조 연산자'라고 부릅니다.


# 간접 참조 연산자

간접 참조 연산자 구문

이 연산자를 사용하면 포인터가 가리키는 
변수의 변숫값을 간접적으로 알 수 있습니다.  

Sample Code

 

 [Sample Code]를 통해 확인해봅시다. 

결과(Result)

위와 같이 pa 포인터에 
간접 참조 연산자(*)를 사용하여 
a의 변수의 변수값을 알 수 있습니다.

 

#변조 

포인터를 사용해서 이렇게 간접적으로
값을 참조할 수 있었습니다.

하지만 포인터로 할 수 있는 일은 
그뿐만이 아닙니다.

포인터로 변수 a를 가리킬 때에는 
다음 그림과 같이 됩니다.

그림 1

 

그리고 그 말은 즉슨,

그림 2

위와 같은 말이 됩니다.


이 성질을 이용하여 

*pa = 20;

위와 작성하여 사용할 수 있습니다.

사실 단순히 변수 a의 값을 바꾸는 것이 
목적이라면 *pa에 값을 대입하는 것보다
a에 직접 대입하는 것이 훨씬 효율적이고,
쉬울 것입니다.

 

하지만 함수의 파라미터를 포인터로 받아서 

call by reference를 사용해 

속도를 향상 시키거나 파일 입출력

등 다른 장치들과 연결을 할 때 많이 사용한다는 점이

장점이라고 볼 수 있습니다. 

 

# call by reference 

-함수 보고서의 가인수와 실인수 부분을 보고 오신 분이라면 

 아마 어렵지 않게 넘어가실 수 있을거라고 생각합니다.

위와 같은 방법을 call by reference라고 합니다.

여기서 중요한 것은

바로 이 부분 입니다. 함수에 값이 아니라 주소를 넘겨주는 것이죠.

기존에 값을 넘겨주는 것을 call by value라고 하는데요.

위 코드는 주소를 넘겨주어

포인터 변수로 그 변수를 참조하여 활용하는 형식입니다

실행 결과

main() 함수에서 만든 변수의

주소를 함수의 파라미터(인수)로 받고

그 주소를 포인터 변수를 사용해

참조하여 값을 변경 시키는 함수입니다.

 

call by value의 사용으로 얻을 수 있는 점은

만약 큰 자료를 넘겨야 된다면

그 자료의 메모리 주소만 넘겨주면 되기 때문에

프로그램 속도가 향상 된다는 점이 있습니다.

 

 

# 포인터 사용 시 주의할 점

- 포인터 변수는 반드시 일반 변수와 같이 주소를 대입 
  시킨 후 사용해야 합니다.

위 코드는 포인터가 그 "무엇도 
가리키지 않는 상태"입니다.
이렇게 해서는 pa *pa든 의미 있는 값을
얻을 수 없습니다.

그렇기 때문에 포인터는 꼭 주소를
대입하고 사용해야 합니다.


# 포인터의 장단점

장점:
      - 메모리를 직접 다룰 수 있어 효율적인
        프로그래밍이 가능합니다.

     ex) call by reference 


단점: 
      - 포인터가 운영체제가 사용하는 메모리           

        공간이나 프로그램을 가리킬 수 있기 
        때문에 위험 부담이 생깁니다. 
        때문에 다른 프로그래밍 언어는 
        포인터를  쓰지 않습니다. 


# 끝 

블로그에서 잘못된 설명이나 오타가 
있으시거나, 궁금하신 점이 있다면
모두 댓글로 꼭! 꼭 남겨주시길 바랍니다,