가변 인자 함수 : 함수의 전달값(파라미터)(인수) 의 개수가 변경될수있는 함수.

ex) printf, scanf


예제

#include <stdio.h>
#include <stdarg.h>

void va_fct(int nFix, ...); //가변 인자 함수 선언

int main(void)
{
    va_fct(3, 1, 2, 3);
    return 0;
}

void va_fct (int nFix, ...);
{
    int i;
    va_list    list; //list 포인터

    va_start (list, nFix); //list 포인터 초기화

    for (i=0 ; i<nFix ; i++) {
        printf ("%d ", va_arg(list, int));
    }
    printf("\n");

    va_end(list); //list reset
}

 1 2 3


  •  va_list : 전달된 인수들은 스택에 저장되고 함수는 스택에서 인수를 꺼내쓴다.  va_list 타입은 char*형으로 정의되어 있고 가변인수를 읽기 위한 포인터 변수다.
  • va_start(list, 마지막고정인수) :  list 포인터 변수가 첫번째 가변인수를 가리키도록 초기화한다. 마지막 고정인수의 번지에 길이를 더해서 가변인수가 시작되는 번지를 계산한다.
  • va_arg(list, 인수타입) : 가변인수를 실제로 읽는 명령어, list 위치에서 인수타입에 맞는 값을 읽고 리턴하여 list를  다음 가변인수의 위치로 옮겨준다. va_arg는 매크로 함수이기 때문에 타입명이 내부적으로 sizeof 연산자와 캐스트연산자로 전달되어 인수로 받을 수 있다.
  • va_end(list) 가변인수를 다 읽은후 reset.


가변 인자 함수의 조건

  • 반드시 하나이상의 고정인수를 가져야한다. 가변인수를 읽기위해 포인터 list를 초기화하기위해 마지막 고정 인수의 번지를 알아야하기때문이다. 고정인수가 없으면 vs_start매크로가 동작하지않는다.
  • 함수 내부에서 자신에게 전달된 가변인수의 개수를 알수있어야한다. 인수의 개수에는 제한이없고 컴파일러가 인수의 개수를 점검하지않으므로 함수가 인수의 개수를 파악할수있게 정보를 제공해야한다.
  • 함수 내부에서 각각의 가변인수타입을 알 수 있어야한다. va_arg매크로가 list번지에서 가변 인수를 읽을때 얼만큼 어떤 타입으로 해석할지를 알아야하기때문이다. 하나의 고정인수를 통해서 모든 가변인수의 타입을 알수있게하는 방식이 가장 좋다.


'dev > C' 카테고리의 다른 글

callback  (0) 2013.05.29
시간 측정을 위한 gettimeofday 사용예제  (0) 2012.12.19
[C언어] assert()  (0) 2010.11.09
문자열 처리 함수  (0) 2010.11.05

+ Recent posts