web-dev-qa-db-ja.com

C構造体の配列

構造体に2つの配列を配置したいのですが、これらは最初に初期化されますが、さらに編集が必要です。特定の構造体にインデックスを付けて、必要に応じて変更できるように、構造体の3つのインスタンスが必要です。出来ますか?

これは私ができると思っていたものですが、エラーが発生します:

struct potNumber{
    int array[20] = {[0 ... 19] = 10};
    char *theName[] = {"Half-and-Half", "Almond", "Rasberry", "Vanilla", …};
} aPot[3];

次に、次のように構造体にアクセスします。

 printf("some statement %s", aPot[0].array[0]);
 aPot[0].theName[3];
 …
14
Greg

構造体自体にはデータがありません。構造体タイプのオブジェクトを作成し、オブジェクトを設定する必要があります...

struct potNumber {
    int array[20];
    char *theName[42];
};

/* I like to separate the type definition from the object creation */
struct potNumber aPot[3];
/* with a C99 compiler you can use 'designated initializers' */
struct potNumber bPot = {{[7] = 7, [3] = -12}, {[4] = "four", [6] = "six"}};

for (i = 0; i < 20; i++) {
  aPot[0].array[i] = i;
}
aPot[0].theName[0] = "Half-and-Half";
aPot[0].theName[1] = "Almond";
aPot[0].theName[2] = "Rasberry";
aPot[0].theName[3] = "Vanilla";
/* ... */

for (i = 0; i < 20; i++) {
  aPot[2].array[i] = 42 + i;
}
aPot[2].theName[0] = "Half-and-Half";
aPot[2].theName[1] = "Almond";
aPot[2].theName[2] = "Rasberry";
aPot[2].theName[3] = "Vanilla";
/* ... */
13
pmg

Cでは、構造体配列の要素は固定サイズでなければならないので、char *theNames[] 有効じゃない。また、そのように構造体を初期化することはできません。 Cでは、配列は静的です。つまり、配列のサイズを動的に変更することはできません。

構造体の正しい宣言は次のようになります

struct potNumber{
    int array[20];
    char theName[10][20];
};

次のように初期化します:

struct potNumber aPot[3]=
{
    /* 0 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    },
    /* 1 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    },
    /* 2 */
    { 
        {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 /* up to 20 integer values*/ },
        {"Half-and-Half", "Almond", "Raspberry", "Vanilla", /* up to 10 strings of max. 20 characters */ }
    }
};

しかし、私はこれがあなたが望むものではないと確信しています。これを行う正しい方法は、いくつかの定型コードを必要としました:

struct IntArray
{
    size_t elements;
    int *data;
};

struct String
{
    size_t length;
    char *data;
};

struct StringArray
{
    size_t elements;
    struct String *data;
};
/* functions for convenient allocation, element access and copying of Arrays and Strings */

struct potNumber
{
    struct IntArray array;
    struct StringArray theNames;
};

個人的には、裸のC配列を使用しないことを強くお勧めします。ヘルパー構造体と関数を介してすべてを実行することで、バッファーのアンダーラン/オーバーランやその他のトラブルから解放されます。すべての真面目なCコーダーは、時間の経過とともにこのようなもので実質的なコードライブラリを構築します。

9
datenwolf