。공부 。

[C언어] 포인터를 배열이름처럼 활용해보자

kyoe 2008. 1. 18. 23:02
배열역시 포인터이기 때문에 포인터변수에 배열이름의 주소값을 대입할수있습니다.
이말은 즉 포인터변수는 배열의 첫번째요소의 주소로 초기화를 시킬수있고 그곳을 가르킬수있다는 겁니다. 또한 포인터는 자료형을 갖고 있기때문에 배열과 마찬가지로 배열의 요소를 포인터연산을 통해 가르키를값을 변경시킬수도 있을 것입니다.
지금부터 그예를 들어 포인터연산을 통해 포인터변수의 값을 변경해보도록하죠.

int array[3] = {1,2,3,};
int형 데이터 3개를 저장할수있는 배열 array를 선언하고 요소를 1,2,3초기화 해줍니다.

int* pp = array;   //배열이름은 배열의 첫번째 요소의 주소를 값으로 갖는다.
int형 포인터변수 pp에 배열 array의 주소값으로 초기화 즉 array의 첫번째 요소의 주소로 초기화합니다.
이렇게 되면 포인터 pp는 array의 첫번째요소를 가르키게 됩니다.

우리가 배열의 요소값을 출력할때 어떻게 했죠? 그렇습니다. array[0],array[1]... 이렇식으로 배열의 값을 출력할수 있었습니다. 포인터역시 배열과 똑같이 사용할수있습니다.
printf("%d, %d, %d \n",pp[0],pp[1],pp[2]);
이렇게 배열과 완전히 같게 쓸수가 있습니다.

하지만 우리는 이렇게 쓰기전에 아래와같이 포인터연산을 통해 포인터 pp가 가르키는 주소값을 변경할수있다는것 부터 안뒤에 써야겠죠?
printf("%d, %d, %d \n",*(pp+0),*(pp+1),*(pp+2));
포인터는 자료형을 갖는다고 위에서도 설명을 드렸고 우리는 int형 배열을 선었했죠 이렇게 되면 배열의 한개한개 요소는 4byte를 갖게 되고 포인터 pp역시 4byte의 공간을 참조하게 됩니다.
예를 들어 배열의 첫번째 요소의 주소값을 0x0010 이라 해둡시다 그럼 두번째 요소의 주소값을 당연히 4byte증가한 0x0014가 되겠죠?
잠깐 여기서 만약 *(pp+1) 이렇게 써주지 않고 *pp+1을 써주면 어떻게 될까요? 이렇하면 포인터pp의 주소값이 증가되지 않고 포인터pp가 가르키는 값이 증가 될겁니다.
우리는 우선순의에 의해서 괄호안의 값이 먼저 연산되는것을 알고 있습니다. 그럼 pp의 값이 증가되고  즉 pp는 array의 주소를 갖고 있기때문에 주소값을 1증가시킨뒤 * 연산을 하게되는겁니다 이렇게되면 결국엔 증가한 주소의 값을 가르키는것이죠.
여기까지 말하면 대충 아~ 하고 감이 오는분들도 계실겁니다. 
첫번째 *(pp+0) 은 포인터 pp의 값을 0만큼증가시켰기때문에 가르키는곳음 처음과 일치합니다. 하지만 *(pp+1)은 포인터 pp의 값을 1만큼증가시키고 그값을 가르키고 있네요 포인터값이 1증가 됬으니까 포인터 pp는 0x00011을 가르킬거라고요? 아니겠죠.. 포인터 pp는 int형 포인터이기때문에 +1을 해주면 4byte가 증가하게 되는겁니다 즉 배열요소 첫번째 주소 값에서 4byte가 증가한 0x0014를 가르키게 되죠.
만약 char형이라면 값을 +1증가시킬때 1byte씩증가가 되고 double형이면 8byte씩 증가 하게 됩니다.
array[i] == *(pp+i) 가 성립하게 되는것이죠.
배열을 *(array+i)  이렇게 쓸수도 있다는겁니다.

아래와같이 사용해도 무방합니다.
printf("%d, ",*(pp));
printf("%d, ",*(++pp));
printf("%d\n",*(++pp));
참! 여기서 알고 넘어가야 할것이 있는데 왜 여기선 위에서 처럼 한줄로 코딩을 하지 않았을까요?