728x90
반응형
포인터와 배열의 관계
- 포인터와 배열은 매우 긴밀한 관계를 맺고 있으며, 어떤 부분에서는 서로를 대체할 수도 있다.
- 배열의 이름은 그 값을 변경할 수 없는 상수라는 점을 제외하면 포인터와 같아서, 따라서 배열의 이름은 포인터 상수(constant pointer)다.
- 포인터 상수(constant pointer)란 포인터 변수가 가리키고 있는 주소 값을 변경할 수 없는 포인터를 의미하며, 상수 포인터(pointer to constant)란 상수를 가르키는 포인터를 의미한다.
int arr[3] = {10, 20, 30}; // 배열 선언
int* ptr_arr = arr; // 포인터에 배열의 이름을 대입함
printf("배열의 이름을 이용하여 배열 요소에 접근 : %d %d %d\n", arr[0], arr[1], arr[2]);
printf(" 포인터를 이용하여 배열 요소에 접근 : %d %d %d\n", ptr_arr[0], ptr_arr[1], ptr_arr[2]);
printf("배열의 이름을 이용한 배열의 크기 계산 : %d\n", sizeof(arr));
printf(" 포인터를 이용한 배열의 크기 계산 : %d\n", sizeof(ptr_arr));
// 배열의 이름을 이용하여 배열 요소에 접근 : 10 20 30
// 포인터를 이용하여 배열 요소에 접근 : 10 20 30
// 배열의 이름을 이용한 배열의 크기 계산 : 12
// 포인터를 이용한 배열의 크기 계산 : 8
- 위의 예제에서는 포인터에 배열의 이름을 대입한 후, 해당 포인터를 배열의 이름처럼 사용한다. 이처럼 C언어에서는 배열의 이름을 포인터처럼 사용할 수 있을 뿐만 아니라, 포인터를 배열의 이름처럼 사용할 수도 있다.
- 하지만 배열의 크기를 계산할 때에는 배열의 이름과 포인터 사이에 차이가 발생한다. 배열의 이름을 이용한 크기 계산에서는 배열의 크기가 int형 배열 요소 3개의 크기인 12바이트로 제대로 출력된다. 하지만 포인터를 이용한 크기 계산에서는 배열의 크기가 아닌 포인터 변수 자체의 크기가 출력되는 차이가 있다.
배열의 포인터 연산
- 다음 예제는 앞선 예제와는 반대로 배열의 이름을 포인터처럼 사용하는 예제다. 배열의 이름으로 포인터 연산을 수행하여 각각의 배열 요소에 접근한다.
int arr[3] = {10, 20, 30}; // 배열 선언
printf(" 배열의 이름을 이용하여 배열 요소에 접근 : %d %d %d\n", arr[0], arr[1], arr[2]);
printf("배열의 이름으로 포인터 연산을 해 배열 요소에 접근 : %d %d %d\n", *(arr+0), *(arr+1), *(arr+2));
// 배열의 이름을 이용하여 배열 요소에 접근 : 10 20 30
// 배열의 이름으로 포인터 연산을 해 배열 요소에 접근 : 10 20 30

- 따라서 배열의 이름과 포인터 사이에는 다음과 같은 공식이 성립함을 알 수 있다.
- 아래 공식은 1차원 배열뿐만 아니라 다차원 배열에서도 언제나 성립한다.
arr이 배열의 이름이거나 포인터이고 n이 정수일 때,
arr[n] == *(arr + n)
- 배열에 관계된 연산을 할 때는 언제나 배열의 크기를 넘어서는 접근을 하지 않도록 주의해야 한다. 포인터 연산을 이용하여 계산하다가 배열의 크기를 넘어서는 접근을 하는 경우, C 컴파일러는 어떠한 오류도 발생시키지 않는다. 다만 잘못된 결과만을 반환하므로 C언어로 프로그래밍할 때에는 언제나 배열의 크기에도 주의해야 한다.
포인터 배열
- 포인터 배열이란 배열 요소로 포인터 변수를 가지는 배열을 의미한다. 즉, 포인터 변수를 저장할 수 있는 배열을 의미한다.
int i, arr_len;
int num01 = 10, num02 = 20, num03 = 30;
int* arr[3] = {&num01, &num02, &num03}; // int형 포인터 배열 선언
arr_len = sizeof(arr)/sizeof(arr[0]);
for (i = 0; i < arr_len; i++) {
printf("%d\n", *arr[i]);
}
// 10
// 20
// 30

배열 포인터
- 배열 포인터란 배열을 가리킬 수 있는 포인터를 의미한다.
- 앞서 배열의 이름은 그 값을 변경할 수 없는 상수라는 점을 제외하면 포인터와 같다고 했다. 이렇게 배열 이름이 있는데도 따로 배열 포인터를 정의하여 사용하는 이유는 2차원 이상의 배열을 가리킬 때 포인터를 통해 배열과 같은 인덱싱을 할 수 있도록 하기 위해서다. 즉, 포인터를 배열처럼 사용하기 위해서 배열 포인터를 정의하여 사용한다.
- 따라서 배열 포인터는 1차원 배열에서는 아무런 의미가 없으며, 2차원 이상의 배열에서만 의미를 가집니다.

- 위의 그림에서 보면 2차원 배열의 배열 이름 arr는 부분 배열 arr[0]와 같은 곳을 가리킨다. 2차원 배열의 배열 이름으로 포인터 연산을 하면 배열의 행 단위로 이동하게 된다. 즉, (arr+1)은 arr[1]과 같은 곳을 가리키게 된다.
- 다음 예제는 2차원 배열에서 각 부분 배열의 시작 주소가 가리키는 메모리에 저장된 데이터를 출력하는 예제다.
int arr[2][3] = {
{10, 20, 30},
{40, 50, 60}
};
printf("%d\n", *arr[0]);
printf("%d\n", *arr[1]);
// 10
// 40
- 2차원 배열에서는 포인터 연산 시 증가하는 값이 행의 길이에 따라 차이를 보이게 된다.
- 2차원 배열의 행의 길이란 부분 배열의 크기를 의미하며, 다음 수식으로 구할 수 있다.
sizeof(arr[0]) / sizeof(타입)
- 다음 예제에서 포인터 연산 시 증감하는 값의 크기는 int형 타입의 크기인 4바이트에 배열 행의 길이인 3를 곱한 12바이트가 된다.
int arr[2][3];
- 따라서 위의 예제에서 배열 이름 arr의 타입은 정확하게 다음과 같이 정의할 수 있다.
- 배열의 이름 arr는 int형 데이터를 가리키는 배열 포인터다.
- 이 배열 포인터는 포인터 연산 시 증감하는 값의 크기가 12바이트다.
- 따라서 위의 예제에서 배열 arr를 가리키는 배열 포인터는 다음과 같이 선언할 수 있다.
int (*pArr)[3];
// 위의 배열 포인터는 다음과 같은 배열들을 가리킬 수 있다
int arr01[2][3];
int arr02[3][3];
int arr03[4][3];
...
- 다음 예제는 배열 포인터를 사용하여 배열과 같은 인덱싱 방법으로 배열 요소를 참조하는 예제다
int arr[2][3] = // 배열의 선언
{
{10, 20, 30},
{40, 50, 60}
};
int (*pArr)[3] = arr; // 배열 포인터의 선언
printf("%d\n", arr[1][1]); // 배열 이름으로 참조
printf("%d\n", pArr[1][1]); // 배열 포인터로 참조
// 50
// 50
포인터 배열과 배열 포인터의 구분
- 앞선 예제의 배열 포인터에서 괄호(())를 생략하면 전혀 다른 의미가 된다.
1. int (*pArr)[3]; // int형 데이터를 저장할 수 있는 2차원 배열을 가리키는 배열 포인터
2. int* pArr[3]; // int형 데이터를 가리킬 수 있는 포인터 변수를 모아 놓은 배열을 가리키는 포인터 배열
main() 함수의 인수 전달
- main() 함수는 프로그램이 실행되면 제일 먼저 자동으로 호출되는 함수다.
- main() 함수도 함수이기 때문에 인수를 전달받을 수도 있고, 반환값을 가질 수도 있다.
// C언어의 main() 함수의 원형
void(또는 int) main(int argc, char *argv[]);
- C언어의 main() 함수의 첫 번째 인수는 int형 변수인 argc로 main() 함수에 인수로 전달되는 문자열의 개수를 명시한다.
- 두 번째 인수는 char형 포인터 배열인 argv로 main() 함수에 인수로 전달된 각각의 문자열이 저장된 배열을 가리킨다.
Reference
728x90
반응형
'Language > C' 카테고리의 다른 글
| [C] C언어 문자와 문자열 - 입출력, 함수 (0) | 2026.06.07 |
|---|---|
| [C] C언어 메모리 관리 - 구조, 스택 프레임, 동적 할당 (0) | 2026.06.07 |
| [C] C언어 포인터 - 개념, 연산, 인수 전달 방법, 이중/void/함수/Null 포인터 (0) | 2026.06.07 |
| [C] C언어 배열 - 1차원, 다차원 (0) | 2026.06.06 |
| [C] C언어 함수 - 정의, 변수의 유효 범위, 재귀 호출 (0) | 2026.06.06 |