va_arg, va_copy, va_end, va_start

Değişken-bağımsız değişken listelerine erişir.

Sözdizimi

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)

Parametreler

type
Alınacak bağımsız değişkenin türü.

arg_ptr
Bağımsız değişken listesinin işaretçisi.

dest
Başlatılacak bağımsız değişkenler listesinin işaretçisi src

src
öğesine kopyalanacak bağımsız değişkenlerin başlatılmış listesinin işaretçisi dest.

prev_param
İlk isteğe bağlı bağımsız değişkenden önce gelen parametre.

Dönüş değeri

va_arg geçerli bağımsız değişkeni döndürür. va_copyögesini va_start seçin ve va_end değerleri döndürmeyin.

Açıklamalar

va_arg, va_copy, va_endve va_start makroları, işlev değişken sayıda bağımsız değişken aldığında işlevin bağımsız değişkenlerine erişmek için taşınabilir bir yol sağlar. Makroların iki sürümü vardır: içinde STDARG.H tanımlanan makrolar ISO C99 standardına uygundur; içinde VARARGS.H tanımlanan makrolar kullanım dışıdır, ancak ANSI C89 standartlarından önce yazılmış kodla geriye dönük uyumluluk için korunur.

Bu makrolar, işlevin sabit sayıda gerekli bağımsız değişken ve ardından değişken sayıda isteğe bağlı bağımsız değişken aldığını varsayar. Gerekli bağımsız değişkenler işleve normal parametreler olarak bildirilir ve parametre adları aracılığıyla erişilebilir. İsteğe bağlı bağımsız değişkenlere, bağımsız değişken listesindeki ilk isteğe bağlı bağımsız değişkene bir işaretçi ayarlayan, listeden bağımsız değişkenleri alan ve bağımsız değişken işleme tamamlandığında işaretçiyi sıfırlayan içindeki makrolar STDARG.H (veya VARARGS.H ANSI C89 standardından önce yazılmış kod için) aracılığıyla erişilir.

içinde STDARG.Htanımlanan C standart makroları aşağıdaki gibi kullanılır:

  • va_start işlevine geçirilen bağımsız değişkenler listesindeki ilk isteğe bağlı bağımsız değişkene ayarlar arg_ptr . Bağımsız değişken arg_ptr türüne va_list sahip olmalıdır. Bağımsız değişken, bağımsız değişken prev_param listesindeki ilk isteğe bağlı bağımsız değişkenin hemen önüne gelen gerekli parametrenin adıdır. Yazmaç depolama sınıfıyla bildirilirse prev_param , makronun davranışı tanımsız olur. va_start ilk kez kullanılmadan önce va_arg kullanılmalıdır.

  • va_argtarafından verilen konumdan değerini type alır ve bir sonraki bağımsız değişkenin nerede başlayacağını belirlemek için boyutunu type kullanarak değerini listedeki bir sonraki bağımsız değişkene işaret etmek için artırırarg_ptr.arg_ptr va_arg işlevinde, listeden bağımsız değişkenleri almak için herhangi bir sayıda kullanılabilir.

  • va_copy geçerli durumundaki bağımsız değişkenlerin listesinin bir kopyasını oluşturur. src parametresi ile va_startbaşlatılmış olmalıdır; çağrılarla va_arg güncelleştirilmiş olabilir, ancak ile va_endsıfırlanmamış olmalıdır. tarafından va_arg alınan sonraki bağımsız değişken, 'den destsrcalınan sonraki bağımsız değişkenle aynıdır.

  • Tüm bağımsız değişkenler alındıktan sonra işaretçiyi va_end olarak NULLsıfırlar. va_endişlevi döndürülmeden önce veya va_copy ile va_start başlatılan her bağımsız değişken listesinde çağrılmalıdır.

Dekont

VARARGS'deki makrolar. H kullanım dışıdır ve yalnızca ANSI C89 standartlarından önce yazılmış kodla geriye dönük uyumluluk için tutulur. Diğer tüm durumlarda, STDARGS.H dosyasındaki makroları kullanın.

(Ortak Dil Çalışma Zamanı Derlemesi) kullanılarak /clr derlendiğinde, yerel ve ortak dil çalışma zamanı (CLR) türündeki sistemler arasındaki farklar nedeniyle bu makroları kullanan programlar beklenmeyen sonuçlar oluşturabilir. Bu programı göz önünde bulundurun:

#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*
}

İkinci parametresinin testit bir int veya char*olmasını beklediğine dikkat edin. Geçirilen bağımsız değişkenler 0xffffffff ( unsigned intbir değil int) ve NULL (aslında int, değil char*). Program yerel kod için derlendiğinde şu çıkışı üretir:

-1

(null)

Gereksinimler

Üst bilgi:<stdio.h> ve <stdarg.h>

Kullanım Dışı Üst Bilgi:<varargs.h>

Kitaplıklar

C çalışma zamanı kitaplıklarının tüm sürümleri.

Örnek

// 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

Ayrıca bkz.

Bağımsız değişken erişimi
vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l