モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

可変個引数 (C++をもう一度)

モーダルを閉じる

ステッカーを選択してください

お支払い手続きへ
モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2014/12/22
最終更新最終更新
2017/04/29
記事区分記事区分
一般公開

目次

    低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。

    サンプルコード

    #include <iostream>
    #include <cstdarg>
    #include <cstdio> // vprintf, vsprintf
    using namespace std;
    
    void MyFunc(int first, ...) {
        va_list args; // 入れ物を確保
        va_start(args, first); // 入れ物の中身を引数で初期化
                               // 直前の引数 first を知らせる必要有
    
        // 好きな型の値として引数を shift 取り出し
        // - int 以下の型 (short, char, bool) は int に変換済
        // - double 以下の型 (float) は double に変換済
        // cout << va_arg(args, char) << endl; // char と指定するとエラー
        cout << va_arg(args, int) << endl; //=> 97
        cout << (char)(va_arg(args, int)) << endl; //=> b
        cout << (char)(va_arg(args, int)) << endl; //=> c
    
        va_end(args); // 終了処理
    }
    
    void MyFuncPtr(int dummy, ...) {
        va_list args;
        va_start(args, dummy);
        cout << va_arg(args, char*) << endl;
        const void* vp = va_arg(args, const void*);
        const void* vp_ = va_arg(args, const void*);
        va_end(args);
    }
    
    void MyPrintF(const char* format, ...) {
        va_list args;
        va_start(args, format);
    
        // printf と動作は同じ
        vprintf(format, args); 
    
        // sprintf と動作は同じ
        char str[128];
        vsprintf(str, format, args);
        cout << str << flush;
    
        va_end(args);
    }
    
    int main() {
        // 可変個引数
        // - 最初の引数は特別扱い可能
        // - 引数の型や個数を関数内で取得できない
        // - int 系列引数に double 系列を渡すとエラーは出ずに不具合 (キャストされないため)
        // - double 系列引数に int 系列を渡すとエラーは出ずに不具合 (キャストされないため)
        MyFunc('Z', 'a', 'b', 'c');
        MyFunc('Z', 97.7, 98.8, 99.9); // 不具合。エラーはなく変な出力
        MyFunc('Z', (int)97.7, (int)98.8, (int)99.9); // 自分でキャストすれば一応は回避できる
    
        // ポインタを渡す場合
        // - 変換は一切行われない (short*, char*, bool*, float* であってもそのまま)
        // - 必要に応じて自分で変換して渡しましょう
        // - NULLポインタは 0 で定義される環境があり int 型と混同され得るため
        //   何らかのポインタ型に自分で変換して渡しましょう
        char str[] = "string";
        MyFuncPtr('Z', str,
                  static_cast<const void*>(str),
                  static_cast<const void*>(NULL));
    
        // 可変個引数の関数内で printf や sprintf を実行したい場合
        int n = 1;
        MyPrintF("%d + %d = %d\n", n, n, n+n);
    
        return 0;
    }
    
    Likeボタン(off)0
    詳細設定を開く/閉じる
    アカウント プロフィール画像

    低レイヤーのプログラミングとOS開発が趣味。C言語を使っています。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    >>さらに詳しくステッカーを贈る
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      ログインする

      関連記事