Looking for c Answers? Try Ask4KnowledgeBase
Looking for c Keywords? Try Ask4Keywords

C Language可変の引数


前書き

変数の引数はprintfファミリの関数( printffprintfなど)と他の関数で使用され、毎回異なる数の引数で関数を呼び出すことができるため、 varargsという名前が使用されます

可変引数機能を使用して関数を実装するには、 #include <stdarg.h>使用します。

可変数の引数を取る関数を呼び出すには、スコープ内に末尾の省略記号を含む完全なプロトタイプがあることを確認してvoid err_exit(const char *format, ...);例えば。

構文

  • void va_start(va_list ap、 last ); / *可変引数の処理を開始します。 lastは、省略記号( "...")の前の最後の関数パラメータです。* /
  • のva_arg(va_listのAPを、 タイプ ); / *リスト内の次の可変引数を取得します。正しいプロモートタイプを渡すようにしてください* /
  • void va_end(va_list ap); / *終了引数の処理* /
  • void va_copy(va_list dst、va_list src); / * C99以降:引数のリスト、つまり引数の処理における現在の位置を別のリストにコピーする(例えば、引数を複数回渡す)* /

パラメーター

パラメータ詳細
va_list ap 引数ポインタ、可変引数のリスト内の現在の位置
最終 最後の非可変関数引数の名前です。したがって、可変引数の処理を開始する正しい場所がコンパイラによって検出されます。 register変数、関数、または配列型として宣言することはできません
タイプ (例えば読み込むための可変長引数の昇格されたintのためにshort intの引数)
va_list src コピーする現在の引数ポインタ
va_list dst 記入される新しい引数リスト

備考

va_startva_argva_end 、およびva_copy関数は実際にはマクロです。

必ず va_start最初に呼び出し、一度だけ呼び出すようにしください。最後にva_endを呼び出し、 va_endすべての終了点で1回だけ呼び出すようにしてください。そうしないと、 あなたのシステムではうまくいくかもしれませんが、確かに移植性がないので、バグを招きます。

プロトタイプを使って関数を正しく宣言し、 最後の非可変引数(関数ではなくregisterでも配列型でもない)の制限に注意してください。引数の処理を開始するには少なくとも1つの非可変引数が必要であるため、可変引数のみを取る関数を宣言することはできません。

va_arg呼び出すときは、 昇格された引数型を要求する必要があります。

  • shortするように促進されint (およびunsigned shortも促進され、 intがない限りsizeof(unsigned short) == sizeof(int)それが促進される場合には、 unsigned int )。
  • floatdouble昇格します。
  • signed charint昇格します。 unsigned charsizeof(unsigned char) == sizeof(int)でなければint昇格されます。
  • charは通常int昇格します。
  • uint8_tint16_tようなC99型も同様にプロモートされます。

歴史的な(すなわちK&R)可変引数処理は<varargs.h>宣言されていますが、廃止されたものとしては使用しないでください。標準的な可変引数処理(ここで記述され、 <stdarg.h>宣言されたもの)がC89で導入されました。 va_copyマクロはC99で導入されましたが、その前に多くのコンパイラによって提供されていました。

可変の引数 関連する例