가변인자 (Variadic Arguments)

이대현·2020년 4월 11일

C / CPP

목록 보기
6/28

1. Printf() 함수의 매개변수...?

printf 함수를 재구현하는 ft_printf 프로젝트를 시작하면 서 들게 된 의문이 있다. printf를 사용하면서 우리는 자연스럽게 printf("%d * %d = %d", 3, 5, 3*5)라고 쓰고 있다. 가만보면 printf라는 함수는 인자를 1개만 넣어도 되고, 2개만 넣어도 되고, 3개, 4개 그 이상을 넣어도 문제없이 돌아간다.

이것을 가능하게 하는 가변 인자에 대해 정리해보았다.

2. 가변인자란?

아래 sum 함수의 두 번째 인자로 사용되는 ... 이 가변 인자 혹은 가변 파라미터라고 불리는 것이다. 매개변수로 아무것도 넘겨주지 않을 수도 있고, 혹은 여러 개를 넘겨줄 수도 있다. 이러한 매크로는 함수가 고정된 수의 필수 인수에 가변 수의 선택적 인수가 붙은 형식을 사용한다고 가정한다.

    #include <stdio.h>
    #include <stdarg.h>
    ​
    int sum(int count, ...)
    {
        int res = 0;
        va_list ap;
        int i;
    ​
        va_start(ap, count);
        
        for(i=0; i<count; i++)
            res += va_arg(ap, int);
    ​
        va_end(ap);
    ​
        return res;
    }
    ​
    int main()
    {
        printf("%d\n", sum(10, 1,2,3,4,5,6,7,8,9,10));
    ​
        return 0;
    }
    ​
    출력 결과 >> 55

3. 각 매크로에 대한 설명

va_list

각 가변 인자의 시작 주소를 가리킬 포인터이다.

va_start

    void va_start(va_list ap, variable_name);

va_list로 만들어진 포인터에게 가변인자 중 첫 번째 선택적 인수(variable_name)의 주소를 가르쳐주는 중요한 매크로이다. va_arg(), va_copy(), va_end()에 대한 후속 호출에 대해 ap 포인터를 초기화한다.

  • ap: va_list 로 만든 포인터가 담긴다.
  • variable_name: 인수 목록의 첫 번째 인자 바로 앞에 오는 필수 매개 변수의 이름. 즉, 마지막 고정된 필수 인수가 담긴다.

va_copy

    void va_copy(va_list dest, va_list src);

va_start()를 dest에 적용한 후 src의 현재 상태에 도달하는 데 이전에 사용된 것과 동일한 순서로 va_arg()를 사용한 경우와 같이 dest를 src의 사본으로 초기화한다. va_copy() 또는 va_start()는 동일한 dest에 대한 va_end()의 중간 호출 없이 dest를 다시 초기화하도록 호출해야 한다.

va_arg

    var_type va_arg(va_list ap, var_type);

ap로 지정된 위치에서 지정된 var_type 값을 검색하고 리스트에서 다음 인수를 가리키도록 ap 를 증가 시켜 다음 인수가 시작 되는 위치를 결정한다. 즉, 특정 가변인자를 가리키고 있는 va_list의 포인터를 다음 가변인자로 이동시켜 주는 매크로이다.

  • ap: va_list로 만든 포인터가 담긴다.
  • var_type: int나 long, double과 같은 타입 이름이 담긴다.

var_type을 설정할 때 char, short 의 경우에는 int로 대신 쓰고, flaot의 경우에는 double로 대신 쓴 이후 형 변환을 해주어야 한다.
ex) char ch = (char) va_arg(ap, int);

va_end

    void va_end(va_list arg_ptr);

모든 인수가 검색 된 후 va_end 는 포인터를 NULL로 다시 설정 한다. 즉, 사용한 가변인자 변수를 끝낼때 사용.

4. 반환값

va_arg() 함수는 현재 인수를 리턴한다. va_copy(), va_end(), va_start() 함수는 값을 리턴하지 않는다.

5. 참고

C언어 가변인자(가변파라미터)를 사용해보자

va_arg, va_copy, va_end, va_start

profile
삽질의 기록들 👨‍💻

0개의 댓글