배열과 포인터

1차원 배열과 포인터

  • 1차원 배열의 이름(변수명)은 배열의 시작 주소를 나타낸다.
1
2
3
4
5
6
7
8
9
10
11
int a[5] = {1, 2, 3, 4, 5};
int *p = a;
int *q = &a[1];

printf("p     : %p\n", p);
printf("&a    : %p\n", &a);
printf("&a[0] : %p\n", &a[0]);
printf("a     : %p\n", a);
printf("----------------------\n");
printf("q     : %p\n", q);
printf("&a[1] : %p\n", &a[1]);
1
2
3
4
5
6
7
p     : 0x7ffeeb6b8a10
&a    : 0x7ffeeb6b8a10
&a[0] : 0x7ffeeb6b8a10
a     : 0x7ffeeb6b8a10
----------------------
q     : 0x7ffeeb6b8a14  # (p + 1) int 형 4byte
&a[1] : 0x7ffeeb6b8a14

포인터 참조를 배열처럼 사용하기

  • 배열의 이름(변수명)은 배열의 시작 주소를 나타낸다. (즉, a = &a[0] = &a)
  • 포인터 변수에 배열의 주소를 저장하면, 포인터 변수는 “배열의 시작 주소”를 가진다.
  • 배열은 인덱스 번호를 이용해 배열의 각 요소에 접근한다.
  • 배열 포인터는 포인터의 증감 연산을 통해 배열의 각 요소에 접근할 수 있다.
  • 또한 배열의 이름은 포인터로 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
int a[5] = {100, 200, 300, 400, 500};
int *p = a;

printf("a[0]   : %d\n", a[0]);
printf("a[0+1] : %d\n\n", a[0+1]);

printf("*p     : %d\n", *p);
printf("*(p+1) : %d\n\n", *(p+1));

printf("*(a)   : %d\n", *(a));
printf("*(a+1) : %d\n", *(a+1));
1
2
3
4
5
6
7
8
9
# 출력
a[0]   : 100
a[0+1] : 200

*p     : 100
*(p+1) : 200

*(a)   : 100
*(a+1) : 200
  • 배열 a 와 이에 대한 포인터를 주소값으로 비교해보면
1
2
3
4
5
6
7
| address | variable |   pointer   | value |
| ------- | -------- | ----------- | ----- |
| 0x00100 | a, a[0]  |  p   , a    | 100   |
| 0x00104 | a[1]     |  p+1 , a+1  | 200   |
| 0x00108 | a[2]     |  p+2 , a+2  | 300   |
| 0x0010c | a[3]     |  p+3 , a+3  | 400   |
| 0x00110 | a[4]     |  p+4 , a+4  | 500   |

두 포인터의 감산 연산

  • 포인터 간 간격을 계산할 수 있다.
1
2
3
4
int a[10], *p, *q;
p = &a[6];
q = &a[3];
printf("p-q : %d\n", p-q);
1
p-q : 3

포인터 간 합산 연산은 사용할 수 없다.

포인터의 증감 연산

  • 포인터가 1만큼 증가 또는 감소할 수 있다.
1
2
3
4
5
6
int a[5] = {100, 200, 300, 400, 500};
int *p = a;

printf("*p   = %d\n", *p);
printf("*p++ = %d\n", *p++);
printf("*++p = %d\n", *++p);
1
2
3
4
# 출력
*p   = 100
*p++ = 100
*++p = 300

주의 - 포인터 이동과 값 증가를 혼동하지 말 것

1
2
3
4
int a[2][3] = { {100, 200, 300}, {400, 500, 600} };
int *pt = a[0];
printf("*(pt+1) : %d\n", *(pt + 1));
printf("*(pt)+1 : %d\n", *(pt) + 1);
1
2
3
# 출력
*(pt+1) : 200
*(pt)+1 : 101

주의 - 포인터는 증감연산이 가능하지만, 배열은 증감연산이 불가능하다.

1
2
3
4
5
6
int A[5] = {1, 2, 3, 4, 5};
int *p = A;
p++; // OK
printf("%d\n", *p); // 2를 출력
A++; // ERROR
printf("%d\n", *A);
1
2
3
# 출력
2
zsh: segmentation fault  ./array_and_pointer

Reference

C 프로그래밍 (김형근, 곽덕훈, 정재화 공저)
C 프로그래밍 강의 (방송통신대 - 이병래)

Comments