2012-08-25 更新 可変長引数 ================================================================================ C 言語での可変長引数を持つ関数の定義は、以下のようにする。 1. 仮引数は、最初の引数に続いて、「...」を続ける 2. 次の va_list 型の変数を定義して、これを使う。 va_list list; 3. 可変長引数を使う準備する va_start(list, 最初の仮引数); 4. 引数を取得する va_arg(list, 仮引数のデータ型) 5. 可変長引数の処理を終了する va_end(list); □ va_func.c --- /* * 可変長引数を確認するサンプル。 */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> int va_func(const char* types, ...); // (1) int main(void) { va_func("idcsxi", 12, 3.14, 'A', "Hello", 56, -78); // (2) return EXIT_SUCCESS; } /** * 可変長引数を受け取り、フォーマットにしたがって表示する。 * @param types 引数のデータ型 * i: int 型 * d: double 型 * c: char 型 * s: char* 型 * @return 正しく表示できた引数の数 */ int va_func(const char* types, ...) { const char* type; int count = 0; va_list list; // (3) va_start(list, types); // (4) for (type = types; *type != '
2012-08-25 更新
可変長引数
================================================================================
C 言語での可変長引数を持つ関数の定義は、以下のようにする。
1. 仮引数は、最初の引数に続いて、「...」を続ける
2. 次の va_list 型の変数を定義して、これを使う。
va_list list;
3. 可変長引数を使う準備する
va_start(list, 最初の仮引数);
4. 引数を取得する
va_arg(list, 仮引数のデータ型)
5. 可変長引数の処理を終了する
va_end(list);
□ va_func.c
---
/*
* 可変長引数を確認するサンプル。
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
int va_func(const char* types, ...); // (1)
int main(void) {
va_func("idcsxi", 12, 3.14, 'A', "Hello", 56, -78); // (2)
return EXIT_SUCCESS;
}
/**
* 可変長引数を受け取り、フォーマットにしたがって表示する。
* @param types 引数のデータ型
* i: int 型
* d: double 型
* c: char 型
* s: char* 型
* @return 正しく表示できた引数の数
*/
int va_func(const char* types, ...) {
const char* type;
int count = 0;
va_list list; // (3)
va_start(list, types); // (4)
for (type = types; *type != '\0'; type++) {
switch (*type) {
case 'i':
printf(" int: %d\n", va_arg(list, int)); // (5)
count++;
break;
case 'd':
printf("double: %f\n", va_arg(list, double)); // (5)
count++;
break;
case 'c':
printf(" char: %c\n", (char) va_arg(list, int)); // (5)
count++;
break;
case 's':
printf("string: %s\n", va_arg(list, char*)); // (5)
count++;
break;
default:
printf("(bad type)\n");
va_arg(list, void*); // 空読みする // (5)
break;
}
}
va_end(list); // (6)
return count;
}
---
□ 実行結果
---
int: 12
double: 3.140000
char: A
string: Hello
(bad type)
int: -78
---
(1) 可変長引数の関数のプロトタイプ宣言
int va_func(const char* types, ...); // (1)
仮引数は少なくてもひとつは必ず書く。次のように、仮引数がひとつもないとコンパイル
エラーになる。
int va_func2(...); // コンパイルエラー
(2) 関数の呼び出し
va_func("idcsxi", 12, 3.14, 'A', "Hello", 56, -78); // (2)
最初の引数が文字列であれば、あとは任意の型をいくつでも引数に取れる。
ただし、今回は、この va_func() の仕様として、文字列中で使用できる文字は、i, d, c,
s のいずれかで、これに対応した型として、引数の中で使用できるのは、int, double,
char, char* だけである。
(3) va_list 型の変数を定義
va_list list; // (3)
この変数は、これ以降の処理で使う。
(4) 可変長引数の処理の開始
va_start(list, types); // (4)
2番目の引数は、関数宣言の、可変長引数の直前の引数を使う。
(5) 仮引数の取得
printf(" int: %d\n", va_arg(list, int)); // (5)
printf("double: %f\n", va_arg(list, double)); // (5)
printf(" char: %c\n", (char) va_arg(list, int)); // (5)
printf("string: %s\n", va_arg(list, char*)); // (5)
va_arg(list, void*); // 空読みする // (5)
仮引数は、va_arg() を使う。
va_arg(v,l)
v: va_list 型の変数
l: 取得したい仮引数のデータ型
なお、つぎの型char は指定できず、警告が出る。実行すると、プログラムはアボートす
る。したがって、対応する型を指定して、キャストする。
char -> int
short -> int
float -> double
また、空読みするときは void* とする。void だと、読み捨てたい引数すら読まれない。
(6) 可変長引数の処理の終了
va_end(list); // (6)
'; type++) { switch (*type) { case 'i': printf(" int: %d\n", va_arg(list, int)); // (5) count++; break; case 'd': printf("double: %f\n", va_arg(list, double)); // (5) count++; break; case 'c': printf(" char: %c\n", (char) va_arg(list, int)); // (5) count++; break; case 's': printf("string: %s\n", va_arg(list, char*)); // (5) count++; break; default: printf("(bad type)\n"); va_arg(list, void*); // 空読みする // (5) break; } } va_end(list); // (6) return count; } --- □ 実行結果 --- int: 12 double: 3.140000 char: A string: Hello (bad type) int: -78 --- (1) 可変長引数の関数のプロトタイプ宣言 int va_func(const char* types, ...); // (1) 仮引数は少なくてもひとつは必ず書く。次のように、仮引数がひとつもないとコンパイル エラーになる。 int va_func2(...); // コンパイルエラー (2) 関数の呼び出し va_func("idcsxi", 12, 3.14, 'A', "Hello", 56, -78); // (2) 最初の引数が文字列であれば、あとは任意の型をいくつでも引数に取れる。 ただし、今回は、この va_func() の仕様として、文字列中で使用できる文字は、i, d, c, s のいずれかで、これに対応した型として、引数の中で使用できるのは、int, double, char, char* だけである。 (3) va_list 型の変数を定義 va_list list; // (3) この変数は、これ以降の処理で使う。 (4) 可変長引数の処理の開始 va_start(list, types); // (4) 2番目の引数は、関数宣言の、可変長引数の直前の引数を使う。 (5) 仮引数の取得 printf(" int: %d\n", va_arg(list, int)); // (5) printf("double: %f\n", va_arg(list, double)); // (5) printf(" char: %c\n", (char) va_arg(list, int)); // (5) printf("string: %s\n", va_arg(list, char*)); // (5) va_arg(list, void*); // 空読みする // (5) 仮引数は、va_arg() を使う。 va_arg(v,l) v: va_list 型の変数 l: 取得したい仮引数のデータ型 なお、つぎの型char は指定できず、警告が出る。実行すると、プログラムはアボートす る。したがって、対応する型を指定して、キャストする。 char -> int short -> int float -> double また、空読みするときは void* とする。void だと、読み捨てたい引数すら読まれない。 (6) 可変長引数の処理の終了 va_end(list); // (6)
最新の画像[もっと見る]
- あけましておめでとうございます 11年前
- 今年もよろしくお願いいたします 12年前
- あけましておめでとうございます 13年前
- あけましておめでとうございます 16年前
※コメント投稿者のブログIDはブログ作成者のみに通知されます