MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
C言語の基礎 - 可変長引数のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
C言語の基礎 - 可変長引数
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == stdarg.hに可変長引数を扱うための機能が用意されている。<br> C言語は関数の仮引数に、"..."を指定することで可変長引数を受け取ることができる。<br> 受け取った可変長引数は、stdarg.hのva_startマクロ、va_argマクロ、va_endマクロのそれぞれを使用することで利用することができる。<br> <br><br> == 可変個数の実引数 == 引数の取得は以下のマクロを用いて手動で行う必要がある。<br> 受け取った可変長引数は、まず、va_startマクロを使用して初期化し、va_argマクロを使用して取得する。使用後は、va_endマクロを使用することで、関数から正常に復帰する。<br> <br> * va_list ap *: イテレート用の情報を保持する型 * va_start(ap, param) *: イテレートを開始 * va_arg(ap, type) *: 次の引数を取り出す * va_end(ap) *: イテレートを終了 <br> 可変長引数の個数を取得することはできない。<br> そのため、関数側には何らかの形で引数の個数を知らせる必要がある。<br> 以下のサンプルコードでは、引数countの値で可変長引数のサイズを明示する。<br> <br><br> == サンプルコード == <source lang="c"> #include <stdarg.h> int sum(int count, ...) { va_list ap; va_start(ap, count); int sum = 0; for (int i = 0; i < count; i++ ) { sum += va_arg(ap, int); } va_end(ap); return sum; } int main() { int s = sum(3, 1, 2, 3); printf("%d", s); // 6 printf("%d", sum((3), 1, 2, 3, 4)); // 6 printf("%d", sum((4), 1, 2, 3, 4)); // 10 printf("%d", sum((2), 1/* , 2 */)); // 無効なバッファを参照するため危険 } </source> <br><br> == その他のテクニック == ===== NULL終端の活用 ===== NULL終端や番兵により、可変長引数の終わりを知らせるテクニックがある。<br> NULLが出現するまで実引数の取り出し操作と比較処理が繰り返される。<br> <source lang="c"> bool strin(const char *target, const char *args, ...) { va_list ap; va_start(ap, args); for (const char *arg = args; arg != NULL; arg = va_arg(ap, const char *)) { if (!strcmp(target, arg)) { va_end(ap); return true; } } va_end(ap); return false; } </source> <source lang="c"> /* 使用例 */ if (strin("a", "A", "a", NULL)) puts("have"); </source> <br> ===== 可変長引数をprintf関数に渡す方法 ===== 先頭引数をprintf関数に渡すだけでは不十分である。<br> 問題なく動く場合もあるが、最悪の場合、プログラムがクラッシュする。<br> printf関数をラップする場合は、vprintf関数を使用する。<br> <source lang="c"> /* 間違った使用例 */ void pf(const char *format, ...) { // 危険 // printf(format); // 警告:Format string is not a string literal (potentially insecure) } </source> <br> <source lang="c"> /* 良い使用例 */ void pf(const char *format, ...) { va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); } </source> <br> <source lang="c"> /* 呼び出し側 */ pf("%s %d", "Shop", 99); // "Shop 99" </source> <br><br> __FORCETOC__ [[カテゴリ:C]]
C言語の基礎 - 可変長引数
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse