C Структуры и массивы - PullRequest
0 голосов
/ 15 июля 2009

Я не могу получить приведенный ниже код для компиляции (см. Ошибки). Будем признательны за рекомендации по исправлению.

#include <stdio.h>

typedef struct {
  char    *fldName;
  unsigned fldLen;
} Field;

typedef struct {
  char    *fldPrompt;
  unsigned startRow;
  unsigned startCol;
} Prompt;

typedef struct {
  Field   *fields[];
  Prompt  *prompts[];
  unsigned numFlds;  <<< invalid field declaration after empty field 
} Form;                    <<< in '(incomplete) struct (no name)'.

Field  firstName = { "fName", 12 };
Field  surName   = { "sName", 25 };
Field  gender    = { "gder", 1 };

Prompt fn        = { "First Name : ", 4, 10 };
Prompt sn        = { "Surname    : ", 6, 10 };
Prompt gn        = { "Gender     : ", 8, 10 };

int main (void)
{
  Form aForm = { { &firstName, &surName, &gender },
                 { &fn, &sn, &gn}, 
                 3 };  <<<  Multiple initializers for the same element
  return 0;             <<<  Too many initializers
}

Ответы [ 6 ]

8 голосов
/ 15 июля 2009

Все ваши ошибки связаны с тем, что вы неправильно объявляете массивы внутри своей структуры. У вас есть для указания размера массива; Вы не можете просто использовать пустые скобки. То есть это будет работать:

typedef struct {
    Field *fields[3];
    Prompt *prompts[3];
    unsigned numFlds;
} Form;

Если вам нужно учитывать различное количество элементов, вам придется использовать что-то еще. Например, вы можете указывать оба поля:

Field **fields;
Prompt **prompts;

Но тогда вам придется динамически выделять и освобождать память для них, и вы определенно не сможете использовать агрегатный инициализатор для инициализации структуры.

4 голосов
/ 15 июля 2009

Вы объявили массивы в определении struct без указания границ. Это невозможно:

typedef struct {
    Field   *fields[];
    Prompt  *prompts[];
    unsigned numFlds; 
} Form;

Вы должны либо указать число в скобках, либо заменить его на тип указателя: Field **fields;. Всегда помните, что размер структуры является статическим и известен во время компиляции, поэтому он не может иметь массив переменного размера внутри себя. Однако он может указывать на массив переменного размера (поскольку указатели имеют постоянный размер).

2 голосов
/ 15 июля 2009

Структура обычно не может содержать элемент с неполным типом (например, массивы без измерений), потому что компилятор не может знать размер этого элемента, то есть смещение следующих элементов в структуре будет неопределенным. Исключением из этого правила является последний член, который может иметь неполный тип массива (так называемый гибкий элемент массива ).

Решение: используйте массивы или указатели фиксированного размера.

0 голосов
/ 15 июля 2009

Похоже, структура связанного списка может наиболее соответствовать вашим потребностям.

Кстати, подсказки и поля всегда отображаются один на один? Если это так, вы можете просто хранить их в одной структуре.

0 голосов
/ 15 июля 2009

Проблема в том, что вы не можете инициализировать массив нулевой длины.

, если вы просите декларацию For:

typedef struct {
    Field   *fields[100];    
    Prompt  *prompts[100];    
    unsigned numFlds;  // <<< invalid field declaration after empty field
} Form;                    // <<< in '(incomplete) struct (no name)'.

Это будет работать.

0 голосов
/ 15 июля 2009

Следующий код [только что изменил и ввел размер массива] и скомпилировал нормально.

#include <stdio.h>

typedef struct {
  char    *fldName;
  unsigned fldLen;
} Field;

typedef struct {
  char    *fldPrompt;
  unsigned startRow;
  unsigned startCol;
} Prompt;

typedef struct {
  Field   *fields[3];
  Prompt  *prompts[3];
  unsigned numFlds;  // invalid field declaration after empty field 
} Form;                    // in '(incomplete) struct (no name)'.

Field  firstName = { "fName", 12 };
Field  surName   = { "sName", 25 };
Field  gender    = { "gder", 1 };

Prompt fn        = { "First Name : ", 4, 10 };
Prompt sn        = { "Surname    : ", 6, 10 };
Prompt gn        = { "Gender     : ", 8, 10 };

int main (void)
{
  Form aForm = { { &firstName, &surName, &gender },
                 { &fn, &sn, &gn}, 
                 3 };   // Multiple initializers for the same element
  return 0;             //  Too many initializers
}

Кроме того, если вам нужно больше 3 в строке 15, вам нужно объявить его двойным указателем, выделить память и использовать ее. Но убедитесь, что освободили / освободили его, когда не собираетесь его использовать. В противном случае это приведет к утечке памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...