본문 바로가기

공부/C언어

(C 예제) 함수의 인자로 배열 전달

함수를 호출할 때

함수이름이 D라고 하면

D(배열이름, 배열의 순서)

 

함수를 만들 때

D( int a[ ], int b )로 하면된다.

배열이름이 복사되서 a로

배열의 순서는 b로 들어온다.


Call-by-Value의 인자전달

기본적으로 값의 복사로 인자전달이 된다.

// 예시
int SimpleFunc(int num) // age에 저장된 값이 매개변수 num에 복사됨
{
	...
}

int main(void)
{
	int age = 17;
	SimpleFunc(age); // 실제로 전달되는 것은 age가 아니라 age에 저장된 값
	...
}

age에 있는 17이라는 숫자가 복사되어 num으로 간다.

 

배열을 함수의 인자로 전달하려면 배열을 통째로 복사할 수 있도록

배열이 매개변수가 되어야 한다. 하지만, C언어는 매개변수로 배열의

선언이 불가능하다.

그래서 C언어에서는 배열을 통째로 복사해서 전달하는 방식 대신에,

배열의 주소 값(배열 이름)을 전달하는 방식으로 대신한다.

 

배열을 함수의 인자로 전달하는 방식

main 함수에서

배열이름 arr이 지니는 주소 값을 전달한다.

 

SimpleFunc 함수에서

배열 이름인 arrrk int형 포인터이므로 매개변수는 int형 포인터 변수이다.

 

위처럼 포인터 변수를 이용해서도 배열의 형태로 접근이 가능하다.


예제

arr1이 12byte를 차지하고

arr2이 20byte를 차지한다.

 

여기에 int의 사이즈인 4byte를 나누면 배열의 길이가 나온다.

 

다른 예제

AddArayElem의 함수부터 보자.

int * param에는 포인터가 들어간다.

len에는 3이 들어간다.

add에는 1, 2, 3이 각각 들어간다.

 

AddArayElem의 for문을 보자.

i가 0부터 2(i < len)까지 1씩 증가하면서 해당되는 배열의 수에 1, 2, 3을

각각 더하면서 반복한다.

 

ShowArayElem의 함수를 보자.

int * param에는 포인터가 들어간다.

len에는 3이 들어간다.

 

ShowArayElem의 for문을 보자.

i가 0부터 2까지 1씩 증가하면서 i에 해당되는 배열의 수를 출력한다.


배열을 함수의 인자로 전달받는 함수의 또 다른 선언

// 이렇게 해도 되지만
void ShowArayElem(int * param, int len)
{
	...
}
void AddArayElem(int * param, int len, int add)
{
	...
}
// 이렇게 해도 된다.
void ShowArayElem(int param[], int len)
{
	...
}
void AddArayElem(int param[], int len, int add)
{
	...
}

둘은 동일한 선언이다.

하지만, 배열을 인자로 전달받는 경우에는 int param[]이 더 알아보기 쉽고

의미있어 보이므로 주로 사용된다.

 

하지만,

// 옳은 예
void main(void)
{
	int arr[3] = { 1,2,3 };
	int * ptr = arr;
}
// 틀린 예
void main(void)
{
	int arr[3] = { 1,2,3 };
	int ptr[] = arr;
}

이렇게는 안된다.


크기 비교 및 정렬하기

https://hcr3066.tistory.com/145

에서 했던 크기를 비교하고 정렬하는 프로그램을 함수를 사용해서 구현해보자.

// 크기 비교 및 정렬하기
#include <stdio.h>

void BubbleSort(int m[], int len)
{
	int i, j, tmp;

	for (i = 0; i < len - 1; i++) {
		for (j = 0; j < len - 1; j++) {
			if (m[j] < m[j + 1]) {
				tmp = m[j];
				m[j] = m[j + 1];
				m[j + 1] = tmp;
			}
		}
	}
}

void main(void)
{
	int n[5];

	printf("숫자 5개 입력: ");
	scanf("%d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &n[4]);

	printf("정렬 전: %d %d %d %d %d", n[0], n[1], n[2], n[3], n[4]);

	BubbleSort(n, 5);

	printf("\n정렬 후: %d %d %d %d %d", n[0], n[1], n[2], n[3], n[4]);
}

함수 BubbleSort는 return하는게 없으므로 void로 시작한다.

 

main에서의 n은 BubbleSort에서 int m[]으로 받는다.

int m[]은 int형 수가 들어가는 배열이다.

 

5는 len으로 받는다.

그렇게되면 n이라는 배열이 m이라는 배열로 바뀌어서

m에서 정렬이 되고 n에서 출력하면 정렬이 된 숫자들이 나온다.

 

이것은 Call-by-reference라고 볼 수 있다.

 

정리하면, 배열을 전달해서 함수를 사용하고 싶으면

배열 주소가 배열 이름이므로, 함수한테 배열 이름과 배열의 순서만 주고,

받을 때는 배열로 받으면 된다.