2016-11-22 8 views
0

C言語の構造体内でconst配列を初期化する最良の方法は何ですか?C言語の構造体内でconst配列を初期化していますか?

typedef struct 
{ 
    float coefs[5]; 

} t_data; 

const float ONETWOTHREEFOURFIVE[5] = {1,2,3,4,5}; 

void init(t_data* data) 
{ 
    data->coefs[0] = ONETWOTHREEFOURFIVE[0]; 
    data->coefs[1] = ONETWOTHREEFOURFIVE[1]; 
    ... 
} 

実際には5つ以上の要素があります。

もっと良い方法がありますか?

+1

'for'ループまたは' memcpy'を使用します。 – user3386109

+1

"... Cの構造体内でconst配列を初期化しています" - 初期化されているターゲット配列はconstではありません。 *ソース*があります。 – WhozCraig

答えて

1

非constの配列を構造体の内部で初期化することを意味しますか?

私はあなたがこの欲しいと思う:あなたが一度に全体構造を割り当てることができる場合、あなたはダミー構造体を作成し、割り当てを使用することができ

memcpy(data->coefs, ONETWOTHREEFOURFIVE, sizeof(ONETWOTHREEFOURFIVE)); 
-1

を:

t_data const ONETWOTHREEFOURFIVE = { {1, 2, 3, 4, 5 } }; 

void init(t_data* data) { 
    *data = ONETWOTHREEFOURFIVE; 
4

あなたはサイズが確信していると仮定すると、同じであれば、memcpyを使用できます。それが不必要にスコープを汚染しないように、私も同様に、ソース・データをローカライズしたい:

void init (t_data* data) { 
    static const float srcData[] = {1,2,3,4,5}; 
    assert (sizeof(data->coeffs) == sizeof(srcData)); 
    memcpy (data->coeffs, srcData, sizeof(data->coeffs)); 
} 

をあなたが私もそこにassertを持って注意してくださいよ、これはあなたが構築しているかどうかを早期に検出することができるようになります2つの配列が同じサイズであるという前提の下で使用されるコードです。これにより、読み取りまたは書き込みのバッファオーバーランを回避できます。

+0

スコープのawarnessをありがとう。 – Danijel

+1

コンパイル時にアサートすることさえできます: 'int comp_assert [sizeof(data-> coeffs)== sizeof(srcData)? 1:-1]; ' – selbie

+0

@selbie +1はコンパイル時にアサートされますが、標準ライブラリから' static_assert'を利用できます。 – user694733

0

私の2セントです。 t_dataに係数の配列以外の要素が含まれている場合は、専用のホルダー構造を使用してループを避けるか、memcpy()を使用できます。また

typedef struct { 
    float c[5]; 
} coef_holder; 

static const coef_holder init_set = { 
    { 1, 2, 3, 4, 5 } 
}; 

typedef struct 
{ 
    coef_holder coefs; 
    /* more stuff */ 
} t_data; 

void init(t_data* data) 
{ 
    data->coefs = init_set; 
    ... 
} 

注意し、この行:

data->coefs = init_set; 

は、それが割り当てで、初期設定ではありません。もちろん、いくつかのアーキテクチャでは、この割り当てはmemcpy()への呼び出しに変換されるかもしれませんが、とにかくソースコードはより明確に見えます。

関連する問題