개요
프로그래밍을 하다 보면 매개변수 개수가 고정되어 있지 않고, 호출할 때마다 전달하는 인자의 개수가 달라지는 함수가 필요한 경우가 있습니다. C/C++ 언어는 이러한 상황을 위해 해결책을 제공하며, 필요에 따라 가변 개수의 매개변수를 받을 수 있는 함수를 정의할 수 있습니다.
다음은 그러한 함수를 정의하는 기본 형태입니다.
int func(int, ... ) {
.
.
.
}
int main() {
func(1, 2, 3);
func(1, 2, 3, 4);
}가변 인자 함수의 규칙
주목해야 할 점은 func() 함수의 마지막 인자가 줄임표(ellipsis), 즉 세 개의 점(...)이라는 것입니다. 그리고 줄임표 바로 앞의 인자는 항상 int형이어야 하며, 이 값은 전달된 가변 인자의 총 개수를 나타냅니다.
이러한 기능을 사용하려면 stdarg.h 헤더 파일을 포함해야 합니다. 이 헤더 파일은 가변 인자 기능을 구현하기 위한 함수와 매크로를 제공합니다. 구체적인 작성 순서는 다음과 같습니다.
- 마지막 매개변수를 줄임표(...)로 정의하고, 그 바로 앞에는 전달될 인자의 개수를 나타내는 int형 매개변수를 배치합니다.
- 함수 정의 내부에 va_list 타입의 변수를 선언합니다. 이 타입은 stdarg.h 헤더 파일에 정의되어 있습니다.
- va_start 매크로와 int형 매개변수를 사용하여 va_list 변수를 인자 목록으로 초기화합니다. va_start 매크로 역시 stdarg.h 헤더 파일에 정의되어 있습니다.
- va_arg 매크로와 va_list 변수를 사용하여 인자 목록의 각 항목에 순차적으로 접근합니다.
- va_end 매크로를 사용하여 va_list 변수에 할당된 메모리를 정리합니다.
예제: 가변 인자의 평균 구하기
이제 위에서 설명한 단계를 따라 가변 개수의 매개변수를 받아 그 평균값을 반환하는 간단한 함수를 작성해 보겠습니다.
#include <stdio.h>
#include <stdarg.h>
double average(int num,...) {
va_list valist;
double sum = 0.0;
int i;
va_start(valist, num); // num개의 인자를 위해 valist 초기화
for (i = 0; i < num; i++) {
// valist에 할당된 모든 인자에 접근
sum += va_arg(valist, int);
}
va_end(valist); // valist를 위해 예약된 메모리 정리
return sum/num;
}
int main() {
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f", average(3, 5,10,15));
}실행 결과
Average of 2, 3, 4, 5 = 3.500000 Average of 5, 10, 15 = 10.000000
위 예제에서 average() 함수는 첫 번째 인자로 인자의 개수를 받고, 나머지 가변 인자들을 순회하며 합계를 계산한 뒤 평균을 반환합니다. 이처럼 stdarg.h의 매크로들을 활용하면 printf()처럼 유연하게 다양한 개수의 인자를 처리하는 함수를 손쉽게 구현할 수 있습니다.