【C言語】stdarg.hを使った可変長引数の処理【標準ライブラリ】
stdarg.hとは?
stdarg.h
は、C言語で可変長引数(引数の数が異なる関数)を処理するためのヘッダーファイルです。
例えば、printf
や scanf
のような関数は、与えられる引数の数や型が可変ですが、stdarg.h
を使うことでこのような関数を作成できます。
基本的な使い方
stdarg.h
を使用するには、次の3つのマクロを利用します:
va_list
: 可変長引数を格納するリスト型va_start
: 引数リストの取得開始va_arg
: 引数リストから1つの値を取得va_end
: 引数リストの使用終了
以下のコードは、可変長引数を受け取る関数の基本形を示しています。
#include <stdio.h>
#include <stdarg.h>
void exampleFunction(int num, ...) {
va_list args;
va_start(args, num);
for (int i = 0; i < num; i++) {
int value = va_arg(args, int);
printf("引数%d: %d\n", i + 1, value);
}
va_end(args);
}
int main() {
exampleFunction(3, 10, 20, 30);
return 0;
}
このコードを実行すると、次のような出力になります。
引数1: 10 引数2: 20 引数3: 30
複数の数値を合計する関数
以下の関数は、任意の数の整数を引数として受け取り、その合計を計算します。
#include <stdio.h>
#include <stdarg.h>
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
va_end(args);
return total;
}
int main() {
printf("合計: %d\n", sum(4, 5, 10, 15, 20));
return 0;
}
出力:
合計: 50
printf関数のような動作をする関数
簡単なカスタムprintf関数の実装例です。
#include <stdio.h>
#include <stdarg.h>
void my_printf(const char *format, ...) {
va_list args;
va_start(args, format);
while (*format) {
if (*format == '%' && *(format + 1) == 'd') {
int num = va_arg(args, int);
printf("%d", num);
format++; // 次の文字をスキップ
} else {
putchar(*format);
}
format++;
}
va_end(args);
}
int main() {
my_printf("Hello %d, world %d!\n", 42, 99);
return 0;
}
出力:
Hello 42, world 99!
複数の文字列を結合する関数
可変長引数を利用して複数の文字列を結合する例です。
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void concatenate(char *buffer, int num, ...) {
va_list args;
va_start(args, num);
buffer[0] = '\0'; // バッファを空にする
for (int i = 0; i < num; i++) {
strcat(buffer, va_arg(args, char *));
}
va_end(args);
}
int main() {
char result[100];
concatenate(result, 3, "Hello ", "C ", "World!");
printf("%s\n", result);
return 0;
}
出力:
Hello C World!
使用上の注意点
- 可変長引数は型チェックが行われないため、正しい型を渡す必要がある。
- 整数以外の型(例: double)は適切にキャストする必要がある。
- 可変長引数を使用する場合は、関数の設計に注意し、引数の数を明示的に指定することが望ましい。
まとめ
stdarg.h
を使用すると、C言語で柔軟な関数を作成できます。
しかし、型チェックが行われないため、正しく使用しないと予期しない動作を引き起こす可能性があります。
用途に応じて慎重に活用してください。