va_arg(), va_copy(), va_end(), va_start() - 関数引数のアクセス

標準

標準/拡張機能 C/C++ 依存項目

ISO C
C99
Single UNIX Specification、バージョン 3

両方  

形式

#include <stdarg.h>

var_type va_arg(va_list arg_ptr, var_type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, variable_name);
C99:
#define _ISOC99_SOURCE
#include <stdarg.h>

var_type va_arg(va_list arg_ptr, var_type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, variable_name);
void va_copy(va_list dest, va_list src);

機能説明

va_arg()、va_end()、および va_start() マクロは、関数が必須引数 の修正番号とオプションの引数の変数番号をとるときにその関数に対して 引数をアクセスします。必須引数を通常のパラメーターとして関数に対して宣言し、パラメーター名を介して引数をアクセスします。

va_start() マクロは、後続の va_arg() と va_end() の呼び出しに対応する、arg_ptr ポインターを初期化します。

引数 variable_name は、(, … の前にある) パラメーター・リストの右端の名前付きのパラメーターの ID です。va_arg() マクロの前に va_start() を使用してください。対応する va_start() マクロ呼び出しと va_end() マクロ呼び出しは、同じ関数に入っていなければなりません。variable_name が関数または配列型、あるいは デフォルト引数プロモーションのアプリケーションの後で生じる 型と互換性がない型と一緒にレジスターとして宣言 された場合には、動作は未定義です。

va_arg() マクロは arg_ptr によって指定さ れた ロケーションから指定された var_type の値を 検索し、arg_ptr を増やして、リストの次の引数を 指します。va_arg() マクロは、関数内で任意の回数だけリストから引数を検索 できます。

また、マクロは z/OS® XL C の環境では固定小数点 10 進数サポートを 提供します。sizeof(xx) 演算子は、値を生成するのに使用する サイズ・キャストと型キャストを判別するために使用されます。したがって、x = va_arg(ap, _Decimal(5,2)); などの 呼び出しは有効です。しかし、固定小数点 10 進数のサイズは変数に することはできません。したがって、z = va_arg(ap, _Decimal(x,y)) (ここで x = 5y = 2) などの呼び出しは 無効です。

va_end() マクロは、パラメーター走査の終了を指示する ために一部のシステムで必要です。

va_start() と va_arg() は、#pragma linkage ディレクティブを 使用してリンケージが変更された関数のパラメーター・リストを 処理しません。

stdarg.h と varargs.h は相互に排他的になっています。どちらの #include が最初に来ても、可視のマクロ 形式が決まります。

va_list 型の型定義は、通常 "char *va_list[2]"です。 一部のアプリケーション (特に移植されたアプリケーション) では、va_list 型を "char *va_list" と定義する必要が あります。この代替の va_list 型は、ユーザーがシステム・ヘッダー・ ファイルを入れる前にフィーチャー・テスト・マクロ _VARARG_EXT_ を定義した 場合に使用可能になります。 _VARARG_EXT_ フィーチャー・テスト・マクロが定義されると、va_list は char * va_list として入力され、関数 vprintf()、vfprintf()、vsprintf()、および vswprintf() はこの代替 va_list 型を 使用します。

va_copy() 関数は、va_list 型の変数 (src) のコピー (dest) を作成します。コピーは、src と同じ va_start()、および va_arg() のまったく同じシーケンスのセットを適用した場合と同様になります。

va_copy() が dest を初期化した後、同じ dest に対する va_end() マクロの呼び出しを間に挟まずに、dest を再初期化するために va_copy() マクロを呼び出してはなりません。

戻り値

va_arg() マクロは現行の引数を戻します。

va_end()、va_copy()、および va_start() マクロは、値を戻しません。

CELEBV01
⁄* CELEBV01                                      

   This example passes a variable number of arguments to a function,            
   stores each argument in an array, and prints each argument.                  

 *⁄                                                                             
#include <stdio.h>                                                              
#include <stdarg.h>                                                             
                                                                                
void vout(int max, ...);                                                        
                                                                                
int main(void)                                                                  
{                                                                               
   vout(3, "Sat", "Sun", "Mon");                                                
   printf("¥n");                                                                
   vout(5, "Mon", "Tues", "Wed", "Thurs", "Fri");                               
}                                                                               
                                                                                
void vout(int max, ...)                                                         
{                                                                               
   va_list arg_ptr;                                                             
   int args = 0;                                                                
   char *days[7];                                                               
                                                                                
   va_start(arg_ptr, max);                                                      
   while(args < max)                                                            
   {                                                                            
      days[args] = va_arg(arg_ptr, char *);                                     
      printf("Day:  %s  ¥n", days[args++]);                                     
      }                                                                         
   va_end(arg_ptr);                                                             
}                                                                               
                                                                                
出力:
Day:  Sat
Day:  Sun
Day:  Mon

Day:  Mon
Day:  Tues
Day:  Wed
Day:  Thurs
Day:  Fri
/* This example uses a variable number of arguments for
   fixed-point decimal data types.
   The example works in z/OS XL C only.
 */
#include <stdio.h>
#include <stdarg.h>
#include <decimal.h>

void vprnt(int, ...);

int main(void) {
  int i = 168;
  decimal(10,2) pd01 = 12345678.12d;
  decimal(20,5) pd02 = -987.65d;
  decimal(31,20) pd03 = 12345678901.12345678900987654321d;
  int j = 135;

  vprnt(0, i, pd01, pd02, pd03, j);

  return(0);
}

void vprnt(int whichcase, ...) {
  va_list arg_ptr;
  int m, n;
  decimal(10,2) va01;
  decimal(20,5) va02;
  decimal(31,20) va03;

  va_start(arg_ptr, whichcase);

  switch (whichcase) {
    case 0:
      m = va_arg(arg_ptr, int);
      va01 = va_arg(arg_ptr, decimal(10,2));
      va02 = va_arg(arg_ptr, decimal(20,5));
      va03 = va_arg(arg_ptr, decimal(31,20));
      n = va_arg(arg_ptr, int);
      printf("m    = %d¥n", m);
      printf("va01 = %D(10,2)¥n", va01);
      printf("va02 = %D(20,5)¥n", va02);
      printf("va03 = %D(31,20)¥n", va03);
      printf("n    = %d¥n", n);
      break;
    default:
      printf("Illegal case number : %d¥n", whichcase);
  }

  va_end(arg_ptr);
}
出力:
m    = 168
va01 = 12345678.12
va02 = -987.65000
va03 = 12345678901.12345678900987654321
n    = 135
CELEBV02
⁄* CELEBV02

   These examples use the _XOPEN_SOURCE feature test macro,
   This ecample passes a variable number of arguments to a function,
   stores each argument in an array, and prints each argument.

 *⁄
#define _XOPEN_SOURCE
#include <stdio.h>
#include <varargs.h>

void vout(va_alist)
va_dcl
{
   va_list arg_ptr;
   int args = 0;
   int max;
   char *days[7];

   va_start(arg_ptr);
   max = va_arg(arg_ptr, int);
   while(args < max) {
        days[args] = va_arg(arg_ptr, char *);
        printf("Days:       %s  ¥n", days[args++]);
        }
   va_end(arg_ptr);
}

int main(void)
{
    vout(3,"Sat","Sun","Mon");
    printf("¥n");
    vout(5,"Mon","Tues","Wed","Thurs","Fri");
}
/* This example uses a variable number of arguments for
   fixed-point decimal data types.
   The example works in z/OS XL C only.
 */
#define  _XOPEN_SOURCE
#include <stdio.h>
#include <varargs.h>
#include <decimal.h>


void vprnt(va_alist)
va_dcl
{
  va_list arg_ptr;
  int m, n, whichcase;
  decimal(10,2) va01;
  decimal(20,5) va02;
  decimal(31,20) va03;

  va_start(arg_ptr);
  whichcase = va_arg(arg_ptr, int);

  switch (whichcase) {
    case 0:
      m = va_arg(arg_ptr, int);
      va01 = va_arg(arg_ptr, decimal(10,2));
      va02 = va_arg(arg_ptr, decimal(20,5));
      va03 = va_arg(arg_ptr, decimal(31,20));
      n = va_arg(arg_ptr, int);
      printf("m    = %d¥n", m);
      printf("va01 = %D(10,2)¥n", va01);
      printf("va02 = %D(20,5)¥n", va02);
      printf("va03 = %D(31,20)¥n", va03);
      printf("n    = %d¥n", n);
      break;
    default:
      printf("Illegal case number : %d¥n", whichcase);
  }

  va_end(arg_ptr);
}


int main(void) {
  int i = 168;
  decimal(10,2) pd01 = 12345678.12d;
  decimal(20,5) pd02 = -987.65d;
  decimal(31,20) pd03 = 12345678901.12345678900987654321d;
  int j = 135;

  vprnt(0, i, pd01, pd02, pd03, j);

  return(0);
}
}
#define _ISOC99_SOURCE
#include <stdio.h>                                       
#include <stdarg.h>	
void prnt(int max, ...);                                  
                                                          
int main(void)                                            
      {                                                   
       prnt(8, "0", "1", "1", "2", "3", "5", "8", "13");  
      }                                                   
                                                          
void prnt(int max, ...)                                   
    {                                                     
       va_list src;                                       
       va_list dest;                                      
       int args = 0;                                      
       char *fib[8];                                      
       va_start(src, max);                                
       va_copy(dest, src);                                
       while(args < max) {                                
         fib[args] = va_arg(dest, char *);                
         printf("fib[%d]:  %s  ¥n", args, fib[args++]);
          }                                               
       va_end(dest);                                      
    }                                                     

出力:

fib[0]:  0 
fib[1]:  1 
fib[2]:  1 
fib[3]:  2 
fib[4]:  3 
fib[5]:  5 
fib[6]:  8 
fib[7]:  13

関連情報