포인터로 배열 다루기
- 배열의 모든 값을 출력하는 함수를 만들 때 -> 배열요소의 값을 일일이 전달인자로 주는 것은 한계가 있다.
배열의 선언 int ary[5] = {10, 20, 30, 40, 50}
함수의 호출 ary_prn(ary[0], ary[1], ary[2], ary[3], ary[4]);
-> 모든 배열요소를 일일이 전달인자로 줘야 한다.
함수의 정의 void ary_prn(int a, int b, int c, int d, int e)
{
printf("%d, %d, %d, %d, %d\n", a, b, c, d, e);
}
- 포인터를 사용하면 배열요소의 값을 간단히 처리할 수 있다.
포인터로 배열요소를 참조하자
- 배열은 연속된 기억공간이 할당된다.
- 배열은 첫번째 배열요소의 포인터만 알면 -> 나머지 배열요소의 포인터도 쉽게 알 수 있다.
x x+4 x+8 x+12 x+16
int ary[5]; int int int int int
[0] [1] [2] [3] [4]
- 포인터 연산 : 포인터에 정수값을 더할 때는 포인터가 가리키는 크기를 곱해서 더해준다.
-> 예를 들어 4를 더하면 마지막 배열요소의 포인터가 구해진다.
포인터 + (정수값 * 포인터가 가리키는 자료형의 크기)
&ary[0] + 4 = &ary[0] + (4*sizeof(int)) = 36 + 16 = 52번지
★포인터 연산의 결과는 "저장위치"
- 모든 배열요소의 포인터는 첫번째 배열요소의 포인터에 정수값을 차례로 더하면 구해진다.
int ary[5] = {10, 20, 30, 40, 50};
&ary[0] + 0 = 36 ----> 10 ary[0]
&ary[0] + 1 = 40 ----> 20 ary[1]
&ary[0] + 2 = 44 ----> 30 ary[2]
&ary[0] + 3 = 48 ----> 40 ary[3]
&ary[0] + 4 = 52 ----> 50 ary[4]
- 각 배열요소의 포인터에 참조연산자를 사용하면 모든 값을 참조할 수 있다.
*(&ary[0] + i)
ㄴ-포인터가 가리키는 기억공간 참조
( ~ ) -> 각 배열 요소를 가리키는 포인터를 차례로 계산
->
for(i=0; i<5; i++){
printf("%d\n", *(&ary[0]+i));
}
- 배열명을 포인터 변수에 저장하면 포인터 변수도 배열명처럼 사용.
-> 이 때 포인터 변수는 첫번째 배열요소를 가리킨다.
int *ap = ary;
배열명 = 포인터
- 배열명은 첫 번째 배열요소를 가리키는 포인터를 기호화한 것이다.
★ ary == &ary[0] ★
★ ary + i == &ary[0] + i ★
- 따라서 배열명으로 주소값을 계산하여 모든 배열요소를 참조할 수 있으며 의미상 이해하기 쉽게 배열표현을 주로 사용하는 것이다.
for(i=0; i<5; i++){
printf("%d\n", *(ary+i));
}
->
배열표현 포인터표현
ary[0] == *(ary+0)
ary[1] == *(ary+1)
ary[2] == *(ary+2)
연습문제
- 배열의 평균값 구하기
-> 평균값 : 8.76
포인터를 사용한 배열요소의 참조 정리
- 배열명(ary)을 사용한 배열표현
- 배열명(ary)을 사용한 포인터표현
- 배열명을 저장한 포인터변수(ap)를 사용한 포인터표현
- 배열명을 저장한 포인터변수(ap)를 사용한 배열표현
int ary[5] = {10, 20, 30, 40 50};
int *ap = ary;
배열명 != 포인터변수
- 배열명은 포인터 상수이므로 자신의 값을 바꿀 수 없다.
ary += 2;
ary++;
- 포인터변수는 기억공간이므로 자신의 값을 바꿀 수 있다.
int ary[5]={10, 20, 30, 40, 50};
int *ap=ary;
int i;
for(i=0; i<5; i++)
{
printf("%5d", *ap);
ap++;
}
연습문제
- 배열값 거꾸로 출력
*ap = ary + 4
ap--
배열의 값을 출력하는 함수
- 배열명을 전달인자로 받으므로 매개변수는 포인터변수를 선언
#include <stdio.h>
void ary_prn(int *);
int main()
{
int ary[5]={10, 20, 30, 40, 50};
ary_prn(ary);
return 0;
}
void ary_prn(int *ap)
{
int i;
for(i=0; i<5; i++)
{
printf("%5d", ap[i]);
}
}
- 포인터변수는 배열명이 아니므로 sizeof연산시 포인터변수의 크기만 계산된다.
따라서 포인터변수로 배열요소의 개수를 구할 수 없다.
※ 포인터 변수는 무조건 4바이트!!! ※
sizeof(ap)는 포인터변수의 크기만 계산
- 배열의 크기가 바뀌어도 출력할 수 있는 함수를 만들 때는 배열요소의 개수를 전달인자로 받아야 한다.
호출할 때 -> ary_prn(ary, sizeof(ary)/sizeof(ary[0]));
배열명, 배열요소의 개수
void ary_prn(int *ap, int an)
{
int i;
for(i=0; i<an; i++)
{
printf("%5d", ap[i]);
}
}
배열에 값을 입력하는 함수
- 배열에 값을 입력할 때는 scanf함수에 각 배열요소의 포인터만을 전달인자로 준다.
(즉, 주소연산자 (&)를 사용하지 않는다.)
void ary_input(int *ap)
{
int i;
for(i=0; i<5; i++)
{
scanf("%d", ap+i);
}
}
연습문제
- 배열의 평균값 구하기
배열의 평균 : 86.60
연습문제
- 배열의 최소값 구하기
배열의 최소값 : 1.5