Linuxプログラミング毎週1回-可変長パラメータ
可変長パラメータはC言語ではあまり新鮮なものではありませんが、その応用範囲は広く、基礎知識の範囲に属しているので、この話題をシリーズの最初の文章にするのが適切です.
可変長パラメータとは?printf()を例に挙げます.
上記の例ではprintf()は3つのパラメータを受信し、1つ目は印刷する文字列で、2つのパラメータが含まれています.
* %d
* %s
次の2つのパラメータに対応する実際の値を示します.
* 1
* 2.0
上記の例ではprintf()は3つのパラメータを受信した.次の例を見てみましょう.
printf()は今回1つのパラメータしか受信しませんでした.言い換えればprintf()が受信するパラメータの個数は*可変の*である.これはどのように実現されたのでしょうか.C言語では、関数定義時に「...」を使用できます.を使用して、次のような可変長パラメータを定義します.
まず固定パラメータを一番前に書いて、後ろに「...」を使います.を使用して、この関数が可変長数パラメータを受信することを宣言します.
次に、関数の内部でstdargを使用します.hで定義されたstructといくつかのマクロは、可変長パラメータの読み取りを実現するために使用される.
* va_list
* va_start()
* va_arg()
* va_end()
このいくつかのものの使い方はとても簡単で、stdargで.hのmanpageでは詳しく説明されています.stdargを表示します.hのmanpageでは、次のコマンドを使用できます.
次のような説明があります.
参照
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の上に置きました
このコードについて説明する点があります.
*この中には2つの可変長パラメータの関数があります.1つは平均数を求めるaverage()で、もう1つはprintfをシミュレートするmin_です.printf()
*average()この関数で説明したいのは、最初の固定パラメータは実際に適用する際に不可欠であり、後のパラメータを使用するためにその組み合わせが必要であることです.
* min_printf()この関数で説明したいのは、後の可変長パラメータのデータ型を読み出すのに、最初の固定パラメータの値をどのように使用するかです.
コードの中の説明はもう詳しくて、よく見ることができます.次に、この例の使用方法を示します.
まずgitからコードを移動します.
次に例をコンパイルします.
最後の実行例は、コマンドと出力の結果です.
可変長パラメータとは?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