Linuxプログラミング毎週1回-可変長パラメータ

2389 ワード

可変長パラメータはC言語ではあまり新鮮なものではありませんが、その応用範囲は広く、基礎知識の範囲に属しているので、この話題をシリーズの最初の文章にするのが適切です.
可変長パラメータとは?printf()を例に挙げます.

printf("This is an integer: %d, That is a float: %s", 1, 2.0);

上記の例ではprintf()は3つのパラメータを受信し、1つ目は印刷する文字列で、2つのパラメータが含まれています.
* %d
* %s
次の2つのパラメータに対応する実際の値を示します.
* 1
* 2.0
上記の例ではprintf()は3つのパラメータを受信した.次の例を見てみましょう.

printf("Hello, world!");

printf()は今回1つのパラメータしか受信しませんでした.言い換えればprintf()が受信するパラメータの個数は*可変の*である.これはどのように実現されたのでしょうか.C言語では、関数定義時に「...」を使用できます.を使用して、次のような可変長パラメータを定義します.

a_function(int i, ...);

まず固定パラメータを一番前に書いて、後ろに「...」を使います.を使用して、この関数が可変長数パラメータを受信することを宣言します.
次に、関数の内部でstdargを使用します.hで定義されたstructといくつかのマクロは、可変長パラメータの読み取りを実現するために使用される.
* va_list
* va_start()
* va_arg()
* va_end()
このいくつかのものの使い方はとても簡単で、stdargで.hのmanpageでは詳しく説明されています.stdargを表示します.hのmanpageでは、次のコマンドを使用できます.

man 3 stdarg

次のような説明があります.
参照
The va_start() macro must be called first, and it initializes ap, which can be passed to va_arg() for each argument to be processed.  Calling va_end() signals that there are no further arguments, and causes ap to be invalidated.  Note that each call to va_start() must be matched by a call to va_end(), from within the same function.
簡単に訳すと、まずva_を呼び出すことです.start()を使用してapを初期化し、va_を使用します.arg()は、可変長パラメータを処理する.最後にva_を使用end()でapをクリーンアップします.
実際の例を作ってgithubの上に置きました

https://github.com/liweinan/learnc/blob/master/stdarg.c

このコードについて説明する点があります.
*この中には2つの可変長パラメータの関数があります.1つは平均数を求めるaverage()で、もう1つはprintfをシミュレートするmin_です.printf()
*average()この関数で説明したいのは、最初の固定パラメータは実際に適用する際に不可欠であり、後のパラメータを使用するためにその組み合わせが必要であることです.
* min_printf()この関数で説明したいのは、後の可変長パラメータのデータ型を読み出すのに、最初の固定パラメータの値をどのように使用するかです.
コードの中の説明はもう詳しくて、よく見ることができます.次に、この例の使用方法を示します.
まずgitからコードを移動します.

git clone git://github.com/liweinan/learnc.git

次に例をコンパイルします.

make stdarg.o

最後の実行例は、コマンドと出力の結果です.

% make play_stdarg
./stdarg.o
average: 2.300000
The ultimate answer of life is: 42