Массив в C-структуре

Я хочу иметь два массива в структуре, которые инициализируются при запуске, но нуждаются в дальнейшем редактировании. Мне нужно три экземпляра структуры, чтобы я мог индексировать в определенную структуру и изменять, как я желаю. Возможно ли это?

Это то, что я думал, что могу сделать, но я получаю ошибки:

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];
 …

Ответ 1

У самих структур нет данных. Вам нужно создать объекты типа struct и установить объекты...

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";
/* ... */

Ответ 2

В массиве C struct элементы должны иметь фиксированный размер, поэтому 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-массивы. Выполнение всего с помощью вспомогательных структур и функций позволяет вам избавиться от буфера под /overruns и других проблем. Каждый серьезный C-кодер строит библиотеку поддеробных кодов с такими вещами со временем.