2

同じ型の配列でもある構造体メンバーにc型配列を割り当てる方法は? ここに私の構造体があります:

typedef struct {

  uint8_t type;
  uint8_t data[10];

} MyStruct;

構造体の作成は次のとおりです。

MyStruct myStruct;

これがいくつかの配列の生成です:

uint8_t generatedArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

これが私の課題です:

myStruct.data = generatedArray;
4

6 に答える 6

3

他の回答が述べているように、配列は直接割り当て可能ではなく、次のような関数を使用する必要がありますmemcpy

memcpy(myStruct.data, generatedArray, sizeof(myStruct.data));

でも...

C は長い歴史を持つ言語です。初期の言語には大まかに「小さい」型と「大きい」型の概念があり、前者は直接割り当て可能で、後者はそうではありませんでした。後のいくつかの言語では、すべてが割り当て可能になりました (または関数型言語の場合は値)。

元の C にはプリミティブ型がありました。整数、浮動小数点数など。およびこれらのタイプの配列。前者は「小さい」ため割り当て可能であり、後者は「大きい」ため割り当て可能ではありませんでした。その後、Cは構造を獲得し、これらは「小さい」と判断しました...

したがって、少し奇妙なことに、ある配列を別の配列に直接割り当てることはできませんが、構造体を別の配列に割り当てることができます。特に、配列であるフィールドが 1 つだけの構造体を割り当てることができます...リテラル構造値を記述することもできます。配列値フィールドを持つものを含みます。そして、「型はコメントです」というアプローチのCであるため、配列へのポインターを構造体へのポインターにキャストできます...

上記は、次のような「楽しい」コードを記述できることを意味します。

typedef struct
{
    uint8_t type;
    uint8_t data[10];
} MyStruct;

typedef struct
{
    uint8_t data[10];
} MyArray;

typedef struct
{
    uint8_t type;
    MyArray array;
} MyStruct2;

void arrayAssignment(int x)
{
    MyStruct myStruct;
    MyArray generatedArray = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; // structure literal

    *(MyArray *)&myStruct.data = generatedArray;

    uint8_t generatedArray2[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; // array literal
    *(MyArray *)&myStruct.data = *(MyArray *)generatedArray2;

    MyStruct2 myStruct2;
    myStruct2.array = generatedArray; // no casts at all, but element access is myStruct2.array.data[index]
}

キャスト、インダイレクションなど、または最後の例array.では、コンパイルされたコードでインデックス作成の余分なコストが発生しないことに注意してください。これらはすべて、コンパイラに組み込みの配列割り当てを使用するよう説得するための単純な方法です。

もちろん、多くの人がこれらのテクニックを定期的に使用することに反対するでしょう!

于 2012-10-31T17:33:40.743 に答える
2

配列を相互に代入することはできません。つまり、配列識別子を代入の左側に置くことはできません。右側にある場合、配列はその最初の要素へのポインターに減衰すると言われているため、実際にはチャンク全体を表しているわけではありません。

代わりに使用し、演算子memcpyを介して取得できる配列のサイズを渡す必要があります。sizeof短い配列の場合、最適化コンパイラは、memcpy呼び出しをより効率的な命令に置き換えて、ターゲット アーキテクチャをより有効に活用できる場合があります。

于 2012-10-31T16:09:54.600 に答える
1

配列に割り当てようとしていますが、配列を割り当てることができません。 ただし、配列は左辺値です。

次のオブジェクト型は左辺値ですが、変更可能な左辺値ではありません:

  • 配列型
  • 不完全なタイプ
  • const 修飾された型
  • オブジェクトが構造体型または共用体型であり、そのメンバーの 1 つに const 修飾型がある

代わりにmemcpyを使用する必要があります。sizeof(myStruct.data)memcpy の 3 番目の引数として渡す必要があります。

memcpy(myStruct.data, generatedArray, sizeof(myStruct.data));
于 2012-10-31T16:11:12.693 に答える
0

そのような配列を直接割り当てることはできません。それをコピーする必要があります。

于 2012-10-31T16:10:20.500 に答える
0

あなたのコンパイラがどのようにしてその割り当てをさせたのだろうか。として配列を使用することはできませんmodifiable lvalue。また、配列として使用する場合はrvalue、配列内の最初の要素へのポインターを表します。これを達成する他の方法は、ポインターを使用するか、memcopy()を使用することです。

于 2012-10-31T16:12:17.127 に答える
0

C99 では、複合リテラルと文字列リテラルを初期化子として使用できます ( uint8_t が char と同じビット表現を持つ場合)。

MyStruct myStruct={.data="\1\2\3\4\5\6\7\x8\x9\xa"};
...
MyStruct myStruct;
myStruct = (MyStruct){.data="\1\2\3\4\5\6\7\x8\x9\xa"};
于 2012-10-31T17:01:38.807 に答える