web-dev-qa-db-ja.com

C構造体をインラインで割り当てる方法

typedef struct {
    int hour;
    int min;
    int sec;
} counter_t;

また、コードでは、各メンバー変数を明示的に初期化せずに、この構造体のインスタンスを初期化します。つまり、次のようなことをしたいのです。

counter_t counter;
counter = {10,30,47}; //doesn't work

10:30:47

のではなく

counter.hour = 10;
counter.min = 30;
counter.sec = 47;

このための構文を思い出さないでください、そしてグーグルからこれを行う方法をすぐに見つけませんでした。

ありがとう!

39
mindthief

初期化:

counter_t c = {10, 30, 47};

割り当て:

c = (counter_t){10, 30, 48};

後者は「複合リテラル」と呼ばれます。

77
Steve Jessop

保守性のために、次のように、明示的に識別された変数を持つリスト構文を使用します。

counter_t counter = {.hour = 10, .min = 30, .sec = 47};

または、たとえばインラインを返す場合:

return (struct counter_t){.hour = 10, .min = 30, .sec = 47};

変数が宣言される順序を変更するシナリオを想像できます。変数を明示的に識別しない場合、すべてのコードを調べて変数の順序を修正する必要があります。このように、それはきれいで読みやすいと思います

サイドノート

@AshleyDuncanと@ M.Mが述べたように、この機能はC99 https://stackoverflow.com/a/12122261/2770195 の後にISO C++から削除されましたが、gnu c ++ではサポートされています。

したがって、これをうまく行うことができますが:

g++ -std=gnu++11 main.cpp -o main

上記の例を試すと、エラーがスローされます。

# need an example. I was unable to find. Even clang++ supports it. If you know 
# one, please suggest an edit

このgnu拡張を認識しないISO C++ 11以降をサポートするC++コンパイラーでコンパイルする必要がある場合、単純なコンストラクターを持つクラスを使用する必要があります。

// backup workaround
// not cool
class gnuFTW {
public:
    int hour;
    int min;
    int sec;
    gnuFTW(int hour, int min, int sec) {
        this->hour = hour;
        this->min = min;
        this->sec = sec;
    }   
};

int main(int argc, const char * argv[]) {
    gnuFTW counter = gnuFTW(10,30,47);
    cout << counter.hour << endl;
    return 0;
}
18
MuhsinFatih