va_arg, va_copy, va_end, va_start

가변 인수 목록에 액세스합니다.

구문

type va_arg(
   va_list arg_ptr,
   type
);
void va_copy(
   va_list dest,
   va_list src
); // (ISO C99 and later)
void va_end(
   va_list arg_ptr
);
void va_start(
   va_list arg_ptr,
   prev_param
); // (ANSI C89 and later)
void va_start(
   arg_ptr
);  // (deprecated Pre-ANSI C89 standardization version)

매개 변수

type
검색할 인수의 형식입니다.

arg_ptr
인수 목록에 대한 포인터입니다.

dest
src에서 초기화할 인수 목록에 대한 포인터입니다.

src
dest에 복사할 초기화된 인수 목록에 대한 포인터입니다.

prev_param
첫 번째 선택적 인수 앞에 오는 매개 변수입니다.

반환 값

va_arg는 현재 인수를 반환합니다. va_copyva_end 값을 va_start 반환하지 않습니다.

설명

va_arg, va_copy, va_endva_start 매크로는 함수가 인수의 가변 수를 사용할 때 함수에 대한 인수에 액세스할 수 있는 간편한 방법을 제공합니다. 매크로에는 ISO C99 표준에 STDARG.H 따라 정의된 매크로, 정의된 VARARGS.H 매크로는 사용되지 않지만 ANSI C89 표준 이전에 작성된 코드와의 이전 버전과의 호환성을 위해 유지됩니다.

이러한 매크로는 함수가 고정된 수의 필수 인수에 가변 수의 선택적 인수가 붙은 형식을 사용한다고 가정합니다. 필수 인수는 함수에 대한 일반 매개 변수로 선언되며 매개 변수 이름을 통해 액세스할 수 있습니다. 인수 목록의 첫 번째 선택적 인수에 STDARG.H 대한 포인터를 설정하고, 목록에서 인수를 검색하고, 인수 처리가 완료되면 포인터를 다시 설정하는 매크로(또는 VARARGS.H ANSI C89 표준 이전에 작성된 코드)를 통해 선택적 인수에 액세스합니다.

정의된 STDARG.HC 표준 매크로는 다음과 같이 사용됩니다.

  • va_startarg_ptr을 함수로 전달되는 인수 목록의 첫 번째 선택적 인수로 설정합니다. arg_ptr 인수의 형식은 va_list여야 합니다. prev_param 인수는 인수 목록에서 첫 번째 선택적 인수 바로 앞에 오는 필수 매개 변수의 이름입니다. prev_param이 register 스토리지 클래스로 선언된 경우 매크로의 동작은 정의되지 않습니다. va_arg를 처음으로 사용하기 전에 va_start를 사용해야 합니다.

  • va_argarg_ptr이 제공하는 위치에서 type의 값을 검색하며 type의 크기를 사용하여 목록의 다음 인수를 가리키도록 arg_ptr을 증가시켜 다음 인수가 시작되는 위치를 결정합니다. 함수에서 va_arg를 원하는 횟수만큼 사용하여 목록에서 인수를 검색할 수 있습니다.

  • va_copy는 현재 상태로 인수 목록의 복사본을 만듭니다. src 매개 변수는 va_start로 이미 초기화된 상태여야 하며, va_arg 호출에서 업데이트되었을 수는 있지만 va_end를 통해 다시 설정된 상태여서는 안 됩니다. va_argdest에서 검색하는 다음 인수는 src에서 검색되는 다음 인수와 같습니다.

  • 모든 인수를 검색한 va_end 후 포인터 NULL를 .로 다시 설정합니다. 함수가 반환되기 전에 va_start 또는 va_copy로 초기화된 각 인수 목록에 대해 va_end를 호출해야 합니다.

참고 항목

VARARGS.H 형식의 매크로는 더 이상 사용되지 않으며 ANSI C89 표준이 적용되기 전에 작성된 이전 버전 코드와의 호환성을 위해서만 유지됩니다. 다른 모든 경우에는 STDARGS.H 형식의 매크로를 사용합니다.

(공용 언어 런타임 컴파일)을 사용하여 /clr 컴파일하는 경우 이러한 매크로를 사용하는 프로그램은 네이티브 및 CLR(공용 언어 런타임) 형식 시스템 간의 차이로 인해 예기치 않은 결과를 생성할 수 있습니다. 다음 프로그램을 살펴보세요.

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

void testit (int i, ...)
{
    va_list argptr;
    va_start(argptr, i);

    if (i == 0)
    {
        int n = va_arg(argptr, int);
        printf("%d\n", n);
    }
    else
    {
        char *s = va_arg(argptr, char*);
        printf("%s\n", s);
    }

    va_end(argptr);
}

int main()
{
    testit(0, 0xFFFFFFFF); // 1st problem: 0xffffffff is not an int
    testit(1, NULL);       // 2nd problem: NULL is not a char*
}

위의 코드에서 testit의 두 번째 매개 변수는 int 또는 char*여야 합니다. 전달되는 인수는 0xffffffff(int가 아니라 unsigned int) 및 NULL(실제로는 char*가 아니라 int)입니다. 네이티브 코드용으로 프로그램을 컴파일하면 다음 출력이 생성됩니다.

-1

(null)

요구 사항

헤더:<stdio.h><stdarg.h>

사용되지 않는 헤더:<varargs.h>

라이브러리

모든 버전의 C 런타임 라이브러리입니다.

예시

// crt_va.c
// Compile with: cl /W3 /Tc crt_va.c
// The program below illustrates passing a variable
// number of arguments using the following macros:
//      va_start            va_arg              va_copy
//      va_end              va_list

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

double deviation(int first, ...);

int main( void )
{
    /* Call with 3 integers (-1 is used as terminator). */
    printf("Deviation is: %f\n", deviation(2, 3, 4, -1 ));

    /* Call with 4 integers. */
    printf("Deviation is: %f\n", deviation(5, 7, 9, 11, -1));

    /* Call with just -1 terminator. */
    printf("Deviation is: %f\n", deviation(-1));
}

/* Returns the standard deviation of a variable list of integers. */
double deviation(int first, ...)
{
    int count = 0, i = first;
    double mean = 0.0, sum = 0.0;
    va_list marker;
    va_list copy;

    va_start(marker, first);     /* Initialize variable arguments. */
    va_copy(copy, marker);       /* Copy list for the second pass */
    while (i != -1)
    {
        sum += i;
        count++;
        i = va_arg(marker, int);
    }
    va_end(marker);              /* Reset variable argument list. */
    mean = sum ? (sum / count) : 0.0;

    i = first;                  /* reset to calculate deviation */
    sum = 0.0;
    while (i != -1)
    {
        sum += (i - mean)*(i - mean);
        i = va_arg(copy, int);
    }
    va_end(copy);               /* Reset copy of argument list. */
    return count ? sqrt(sum / count) : 0.0;
}
Deviation is: 0.816497
Deviation is: 2.236068
Deviation is: 0.000000

참고 항목

인수 액세스
vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l