2013년 10월 28일 월요일

C 언어 포인터 이해하기 1 (숫자편)



C언어에서 가장 이해하기 어려운 것이 포인터(pointer)의 개념이다.

아래는 c언어의 포인터를 설명하기위한  C언어 프로그램을 보여주며, 첫째 줄에서 변수를 선언하고, 두번째 줄에서 변수를 초기화하고 있다. 

각 변수의 주소를 알기 위해셔, printf 함수에 포함된 %p를 이용해서  변수의 주소를 인쇄했다.

그리고, 변수명 앞에 위치한 &는 주소를 나타내고, 포인터 * 는 변수에 저장된 주소가 가리키고 있는 곳의 값(맨 아래의 그림의 화살표를 참조)을나타낸다는 것을 알고 시작하자. 




위 프로그램의 p = &i 라는 명령어를 쉽게 알아보자.

이 명령어는, 변수 i 3 A 번지에 저장했다면, B 번지에 위치한 포인터 변수 p A 번지를 저장시키라는 명령어이다. 

먼저 &i는 변수 i의 주소를 가리키므로 p는 포인터 변수, 즉 주소 저장하는 변수 선언되어야 한다.

그리고, *p 변수 선언을 하는 것 외에 사용되면, *p의  의미는 p 저장 A 번지 내용 3을 가리킨다.

따라서, 이 프로그램을 컴파일하여 실행하면 아래와 같은 결과가 나온다.



위의 결과를 설명하면 아래와 같다.

그리고, 편의상 아래의 메모리의 주소는 위의 실행화면의 주소 중에서 마지막 3개만 나타냈다.
  
즉, int 변수 i가 저장된 주소는 E2C 번지이고 이때 저장된  3이다.

이때 p = &i라는 명령어를 만나면, E14 번지에 포인터 변수 p가 할당되고, 그 값은 변수 i의 주소인 E2C 번지가 저장된다.

그리고, 프린트 함수에 포함된 *p의미는 그림의 화살표와 같이 포인터 변수에 저장된 주소(E2C)에 저장된 값인 3을 가리킨다.






여담으로, 위 프로그램은 변수 선언 및 초기화가 아래와 같이 분리되었다.

int i, j, *p, *q;                  // 변수 선언
i = 3; i = 5; p = &i, q = &j;  // 변수 초기화 

하지만, 변수선엄 치 초기화를 한 곳에 합치면 아래와 같이 작성할 수 있다.

int i =3, j=5, *p =&i, *q=&j;  // 변수 선언 및 변수 초기화
  

위의 실행화면에서 에러가 난 것은, 포인터 변수인 *r 이 변수 선언만 되고, 초기화가 안됐기 때문에 생긴 에러이다.

이것은 변수 선언과 초기화가 무엇인지 알려주기 위해서 추가했다.

그러면 훈련으로 아래의 결과를 알아보자.

1. **(&p)
2. 7*(*p) / (*q) + 7   // i, j가 int 형 변수라는 것이 힌트.
3, p == (&i)


답은 3, 11, 1이 된다.