본문 바로가기

공부/C언어

(C 예제) 포인터와 배열

배열 이름이란?

아래의 예제처럼 배열의 이름은 배열의 시작 주소 값을 의미하는 포인터이다.

배열은 메모리 접근에 사용되는 * 연산이 가능하기 때문에 단순한 주소 값이 아니다.

 

▶%p는 포인터 주소값 출력이다.

 

▶주소값이 4씩 차이나는 것은 4byte이기 때문이다.

 

▶3번째 결과에서 n의 주소값이 위와 같다.

그 뜻은 배열이름(n)은 그 자체가 주소이다.

 

▶n의 주소 값은 n[0]의 주소값과 같다.

이 뜻은 위에서도 말했다시피 배열의 이름은 배열의 시작 주소 값을 의미한다.

 

▶n + 1은 &n[1]과 같다.

그러므로 배열이름에 숫자를 더하거나 빼면 주소가 변경된다.

왜냐면 배열이름 그 자체가 주소이기 때문에 더하거나 빼면

그 사이즈(여기서는 int형 4byte)만큼 더하거나 빠지기 때문이다.

 

예를 들어 double형인 배열에 숫자 1을 더하면 8씩 주소가 바뀐다.

 

▶즉, n + k = &n[k]이다.

 

▶여기에 *를 붙이면 이렇게 된다.

* (n + k) = * &n[k]

* &n[k]는 n[k]의 주소값(&)의 *(있는 값)이므로 둘은 상쇄된다고 볼 수 있고

* (n + k) = n[k]가 된다.

그러므로 다섯번째 printf의 출력이 저렇게 된다.

 

깔끔하게 정리하자면

  1. 배열 이름은 그 배열의 주소를 의미한다.
    주소이기 때문에 %p서식을 이용.
  2. 배열 이름은 배열의 첫 번째 시작 주소와 똑같다.
    n = &n[0]
  3. 배열 이름에 숫자를 더하거나 빼면 그 숫자의 사이즈 크기만큼 주소가 바뀐다.
    int-> 4, double -> 8, char -> 1, ...
  4. 배열 이름에 k만큼의 숫자를 더하면 그 배열의 k번째의 주소와 똑같다.
  5. 그러므로 *(n + k) = n[k]가 된다.

이것만큼은 외우자!


1차원 배열 이름의 포인터 형

arr1 주소로 가서 값을 4byte로 읽는다.

arr2 주소로 가서 값을 8byte로 읽는다.

 

배열의 이름이 가리키는 변수의 자료형을 근거로 1차원 배열 이름의 포인터 형을

결정한다.

 

배열의 이름은 배열의 0번째의 주소이기 때문에 출력시

1과 1.1.로 나온다.

 

*arr1은 arr1의 0번째 숫자이다.

여기에 100을 더했으니 출력시 101이 나오고

*arr2도 120.5를 더했으니 121.6이 나온다.


포인터를 배열 이름처럼 사용 가능

배열 이름(첫 주소)를 포인터에 넣으면 

배열 주소가 담겨 있는 포인터 변수로 배열의 값을

사용할 수 있다.

arr은 int형 포인터이다.

int * ptr을 했으니 ptr은 주소(포인터)이다.

여기에 arr[0]의 주소를 넣었다.

 

그러므로 출력은 저렇게 나온다.


포인터를 대상으로 증감연산

 

사실 위의 초기화는 좋지 못한 예이다.

특정 주소를 직접 넣는 것은 컴퓨터가 동작하는데 필요한

필수적인 값이 들어가 있을 수도 있기 때문이다.

 

ptr1에 1을 더했고 int형이니 결과는 10에서 14가 된다.

ptr2에서 2를 더했고 double형이니 16진수로 인해 20이 된다.

 

이처럼 포인터 변수에 저장된 값(주소)을 대상으로 하는

증감연산이 가능하다.(곱셈, 나눗셈은 불가능)

이것은 포인터 연산의 일종이다.


*(ptr + 1)은 ptr[1]과 같으므로 출력결과의 첫번째 줄은 11 22 33으로 나온다.

 

ptr은 11의 주소가 들어가있는데 *했으므로 11이 찍힌다.

거기에 1을 더했으니 22, 또 더했으니 33이 나온다.

또 거기에 1을 빼니 22, 또 빼기 했으니 11이 나온다.


결론

위의 결과로 알 수 있듯이

arr[i]는 *[arr+i]와 같다.

*(ptr+0)은 *ptr과 같다.

*(arr+0)은 *arr과 같다.