2013-10-27 新規 [C] 可変長引数の関数から可変長引数の関数を呼ぶ ================================================================================ 可変長引数の関数から、別の可変長引数の関数を呼び出す。 gcc の拡張機能で、可変長マクロもあるが、あくまでも gcc 拡張なので、可変長引数を 持つ関数を使う。 サンプルとしては、デバッグ用のプリント関数をつくることにする。 デバッグ用なので、マクロ名 NDEBUG が定義されているときは何もしないようにする。そ して、プリントした後に改行し、flush も行う。 また、プリントする関数なので、標準ライブラリー関数 printf() のように、可変長の引 数を受け取るようにする。 仕様としては、以下のとおり。 void debugPrint(const char* tag, const char* format, ...); 引数 tag タグ。 format プリントする書式 ... 可変長引数部分。プリントしたい式や値 なお、この関数の中から、可変長リストを引数にとる関数を呼び出すことにする。 仕様としては、以下のとおり。 void print(const char* tag, const char* format, va_list args); 引数 tag タグ format プリントする書式 args 可変長リスト □ vargs_sample.c --- #include <stdio.h> #include <stdlib.h> #include <stdarg.h> // (1) void debugPrint(const char* tag, const char* format, ...); // (2) void print(const char* tag, const char* format, va_list args); // (3) int main(void) { printf("Start¥n"); debugPrint("TEST", "[%d %d]", 123, 456); // (4) printf("End¥n"); return EXIT_SUCCESS; } void debugPrint(const char* tag, const char* format, ...) { #ifndef NDEBUG // (5) va_list args; // (6) va_start(args, format); // (7) print(tag, format, args); // (8) va_end(args); // (9) #endif } void print(const char* tag, const char* format, va_list args) { printf("%s ", tag); vprintf(format, args); // (10) putchar('¥n'); fflush(stdout); } --- □ 実行結果 --- Start TEST [123 456] End --- (1) #include <stdarg.h> 可変長引数を持った関数を宣言するために必要なヘッダーファイル。 (2) void debugPrint(const char* tag, const char* format, ...); 可変長引数を持った関数のプロトタイプ宣言。 少なくとも、ひとつは引数が必要になる。 だいたいは、この引数に続く可変長部分の形式や数をあらわすものになる。 この使い方は、標準ライブラリー関数の printf() と同じ。 ただし、デバッグ用として、改行が入り、出力した後に flush する。 また、マクロ名 NDEBUG が定義されているときは何も表示しない。 (3) void print(const char* tag, const char* format, va_list args); 可変長の引数をあらわすリスト va_list 型の引数を受け取る関数のプロトタイプ宣言。 この関数は、可変長引数部分を const char* format, ... としてしまうと、実行結果は正しくなくなるので注意。 (4) debugPrint("TEST", "[%d %d]", 123, 456); 可変長の引数を持った関数の呼び出し。 ここでは、デバッグ用のプリント関数 debugPrint() を使っている。 (5) #ifndef NDEBUG デバッグ用のプリント関数なので、マクロ名 NDEBUG が定義されているときは何も行わな いようにする。 (6) va_list args; 可変長引数部分をあらわす (可変長リスト) 型 va_list の変数 args を定義する。 (7) va_start(args, format); 可変長リストを初期化する。 最初の引数は、va_list 型の変数。ここに、可変長リストが入る。 2 番目の引数は、可変長引数の直前の引数名。 (8) print(tag, format, args); 可変長リストを引数としてもつ関数の呼び出し。 普通の関数の呼び出しと一緒。 (9) va_end(args); 可変長リストの処理を終了する。 (10) vprintf(format, args); 可変長リストを持った標準ライブラリー関数 printf 関数の呼び出し。 この部分を、 printf(format, args); とすると、実行結果は正しくないので注意が必要。 以上
最新の画像[もっと見る]
-
あけましておめでとうございます 11年前
-
今年もよろしくお願いいたします 12年前
-
あけましておめでとうございます 13年前
-
あけましておめでとうございます 16年前
※コメント投稿者のブログIDはブログ作成者のみに通知されます