배열의 이름은 포인터이다. 배열의 시작 주소값을 저장하고 있다. 배열의 시작 주소값은 배열 첫 번째 요소의 주소값과 동일하다. 다음 예시를 보면 알 수 있을 것이다.
#include <stdio.h>
int main(void) {
int arr[3] = { 1, 2, 3 };
printf("배열 이름의 주소 : %p\n", arr);
printf("첫 번째 요소 : %d 주소 : %p\n", arr[0], &arr[0]);
printf("첫 번째 요소 : %d 주소 : %p\n", arr[1], &arr[1]);
printf("첫 번째 요소 : %d 주소 : %p\n", arr[2], &arr[2]);
return 0;
}
배열 이름의 주소 : 0053FDF4
첫 번째 요소 : 1 주소 : 0053FDF4
첫 번째 요소 : 2 주소 : 0053FDF8
첫 번째 요소 : 3 주소 : 0053FDFC
👉🏻%p는 주소값을 출력하는 서식문자이다.
위의 예시를 통해 배열의 이름이 첫 번째 원소의 주소값과 동일하다는 것을 알 수 있다.
int형 배열에서 각 원소들은 4바이트씩 연속된 저장공간에 저장되어 있다.
❗배열의 이름은 값을 변경할 수 없는 상수이다. 즉, 상수 형태의 포인터이다.
포인터 변수를 배열의 이름처럼 사용할 수 있다.
다음 예시를 보겠다.
#include <stdio.h>
int main(void) {
int arr[3] = { 1, 2, 3 };
int* ptr = arr;
printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]);
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
return 0;
}
1 2 3
1 2 3
포인터 변수의 증감 연산은 실수, 정수의 증감과는 다르다. 포인터 변수에서 1이 증가/감소하는 것은, 포인터 변수가 가리키는 변수의 자료형의 크기만큼 변화한다는 것이다.
예를 들어 int형 변수를 가리키는 포인터 변수의 경우, +1하면 주소값이 4 증가하고 -1하면 주소값이 4 감소한다.
double형 변수를 가리키는 포인터 변수의 경우 +1하면 주소값이 8 증가하고 -1하면 주소값이 8 감소하게 된다.
이러한 특성으로 인해 포인터를 배열 이름과 같이 사용할 때 증감을 통해 쉽게 접근할 수 있다.
#include <stdio.h>
int main(void) {
int arr[3] = { 1, 2, 3 };
int* ptr = arr;
printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]);
printf("%d %d %d\n", *ptr, *(ptr + 1), *(ptr + 2));
printf("%d %d %d\n", *arr, *(arr + 1), *(arr + 2));
return 0;
}
1 2 3
1 2 3
1 2 3
다차원 배열에서도 유용하게 사용되는 식이므로 기억해두어야한다.
arr[i] == *(arr + i)
1차원 배열을 공부할 때, 문자열의 선언에 대해 공부했었다.
char str[] = "This is string";
위와 같이 문자열을 선언하면, 배열 인덱스를 이용해 문자열의 일부를 변경할 수 있는 변수 형태의 문자열이 만들어졌었다.
포인터를 이용해 문자열을 선언하는 것도 가능하다.
char *str = "This is also string";
이렇게 포인터를 이용해 문자열을 저장하면, 메모리 공간에 문자열이 저장되고 문자열의 첫 번째 문자인 T의 주소값이 반환되어 포인터 변수 str에 저장된다. 이 때 str의 크기는 포인터 변수이므로 8바이트이다. 포인터 변수 str이 가리키는 문자열은 일부를 변경할 수 없다.
다음 그림을 통해 차이점을 이해할 수 있다.
❗배열 str은 배열의 첫 번째 요소의 위치를 가리키며, str이 가리키는 위치는 변경될 수 없다. 하지만 포인터 str이 가리키는 주소값은 언제든지 변경될 수 있다.
포인터는 변수이므로 포인터 변수로 이루어진 배열을 만들 수 있다. 이를 포인터 배열이라 한다.
이 배열은 주소값을 저장한다.
다음과 같이 선언한다.
int *iArr[10];
double *dArr[10];
포인터로 선언된 문자열 또한 배열을 생성할 수 있다. 문자열 배열은 다음과 같이 선언한다.
char *strArr[3];
printf 함수에서 문자열을 출력할 때 서식문자 %s를 사용하는데, 이 때 인자로 주소값을 넣어주어야 한다. 따라서 포인터 배열의 원소를 출력할 때와 문자열 배열의 원소를 출력할 때의 인자 전달은 조금 다르다.