[C언어] 배열과 포인터

이가영·2023년 9월 10일
0

C언어

목록 보기
11/16

포인터로 배열 다루기

  • 배열의 모든 값을 출력하는 함수를 만들 때 -> 배열요소의 값을 일일이 전달인자로 주는 것은 한계가 있다.
배열의 선언 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) //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

포인터를 사용한 배열요소의 참조 정리

  • 포인터(변수)로 배열요소를 참조하는 방법
  1. 배열명(ary)을 사용한 배열표현
  2. 배열명(ary)을 사용한 포인터표현
  3. 배열명을 저장한 포인터변수(ap)를 사용한 포인터표현
  4. 배열명을 저장한 포인터변수(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선언, ary+4해서 초기화 시킴. 3.5를 가리키는 주소값이 ap에 들어감.
ap-- //ap=ap-1;과 같은 의미. 아까 +4씩해서 주소를 연산했는데 지금은 -4씩 해서 주소를 연산할 것이다. 그 전에 저장되어 있는 위치. 그럼 3.5 전에 있는 위치인 2.3을 출력...이렇게 계속 하면 1.5까지 출력됨

배열의 값을 출력하는 함수

  • 배열명을 전달인자로 받으므로 매개변수는 포인터변수를 선언
#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) //배열명을 저장할 포인터변수 선언, ap에 ary들어감★
{
	int i;
	for(i=0; i<5; i++)
    {
		printf("%5d", ap[i]); //포인터변수를 마치 배열명처럼 사용
        //ap[i] = *(ap+i)
	}
}
  • 포인터변수는 배열명이 아니므로 sizeof연산시 포인터변수의 크기만 계산된다.
    따라서 포인터변수로 배열요소의 개수를 구할 수 없다.
    ※ 포인터 변수는 무조건 4바이트!!! ※
sizeof(ap)는 포인터변수의 크기만 계산
//sizeof(ary)/sizeof(ap[0])
  • 배열의 크기가 바뀌어도 출력할 수 있는 함수를 만들 때는 배열요소의 개수를 전달인자로 받아야 한다.
호출할 때 -> 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) //배열명을 지정할 포인터변수 선언. ap <- ary, ap에 36번지들어감
{
	int i;
    for(i=0; i<5; i++) //배열요소의 개수만큼 반복
    {
		scanf("%d", ap+i); //각 배열요소의 포인터를 구해서 전달인자로 줌
        //i가 0이면 36번지, i가 1(x4)이면 40번지...etc. 주소값이므로 &연산자 안 붙는다.
    }
}

연습문제

  • 배열의 평균값 구하기

    배열의 평균 : 86.60

연습문제

  • 배열의 최소값 구하기

    배열의 최소값 : 1.5
profile
gy’s portfolio

0개의 댓글