프로그래밍 언어/[ C ]

[ C ] 12. 함수와 가변인자

kim.svadoz 2020. 8. 14. 09:59
728x90
반응형

[ 함수와 가변인자 ]

printf, scanf와 같이 매개변수의 개수가 정해지지 않은 개수가 있다. 이렇게 매번 함수에 들어가는 인수(argument)의 개수가 변하는 것을 가변 인자(가변 인수, variable argument)라고 한다.

  • 함수에서 가변인자를 정의할 때는 고정 매개변수가 한 개 이상 있어야 하며 고정 매개변수 뒤에 ...을 붙여 매개변수의 개수가 정해지지않았다는 표시를 해준다. 단, ...뒤에는 다른 매개변수를 지정할 수 없다.
반환값 자료형 함수이름(자료형 고정매개변수, ...){

}
#include <stdio.h>

// args는 고정 매개변수
void printNumbers(int args, ...){
    printf("%d ", args);
}

int main(){
    printNumbers(1, 10);
    printNumbers(2, 10, 20);
    printNumbers(3, 10, 20, 30);
    printNumbers(4, 10, 20, 30, 40);

    return 0;
}
# 실행 결과
1 2 3 4
  • 이제 ... 부분의 매개변수를 사용해보자
#include <stdio.h>
#include <stdarg.h>        // va_list, va_start, va_arg, va_end가 정의된 헤더파일

void printNumbers(int args, ...){
    va_list = ap;                // 가변 인자 목록 포인터
    va_start(ap, args);         // 가변인자 목록 포인터 설정
    for(int i=0; i<args; i++){
        int num = va_arg(ap, int);    // int 크기만큼 가변 인자 목록에 서 값을 가져옴
        printf("%d ", num);            // ap를 int 크기만큼 순방향으로 이동
    }
    va_end(ap);                // 가변 인자 목록 포인터를 NULL로 초기화
    printf("\n");
}

int main(){
    printNumbers(1, 100);
    printNumbers(2, 10, 20);
    printNumbers(3, 10, 20, 30);
    printNumbers(4, 10, 20, 30, 40);

    return 0;
}
  • va_list : 가변 인자 목록. 가변인자의 메모리 주소를 저장하는 포인터

  • va_start : 가변 인자를 가져올 수 있도록 포인터를 설정

  • va_arg : 가변인자 포인터에서 특정 자료형 크기만큼 값을 가져옴

  • va_end : 가변 인자 처리가 끝났을 떄 포인터를 NULL로 초기화

  • 함수 안에서는 va_start매크로에 가변인자 목록 포인터 ap와 가변인자 개수 args를 넣어 가변 인자를 가져올 수 있도록 준비한다.(ap = argument pointer)

  • 만약 가변인자가 4개 들어잇는게 printNumbers(4, 10, 20, 30, 40);를 호출한 뒤 va_start 매크로를 실행하면 다음과 같은 모양이 나온다.

image-20200806111153464

  • 이제 반복문으로 가변 인자 개수만큼 반복하면서 va_arg매크로로 값을 가져오면 된다. 이때 va_arg에는 가변 인자의 자료형을 지정한다.
  • int num= va_arg(ap, int);를 실행하면 현재 ap에서 4바이트(int 크기)만큼 역참조하여 값을 가져온 뒤 ap를 4바이트만큼 순방향 이동시킨다.

image-20200806111329035

  • 즉, 반복문에서 반복할 때마다 ap는 4바이트만큼 순방향으로 이동하므로 10, 20, 30, 40을 순서대로 가져올 수 있다.
728x90
반응형