2013-09-21 6 views
0

Я новичок в программировании на языке C и имею следующий код. Я столкнулся с следующей ошибкой."Тип массива имеет неполный тип элемента"

typedef struct Vertex Vertex; 
typedef struct Edge Edge; 

struct Vertex { 
    bool known; 
    char id[25]; 
    Edge edges[20]; 
    int distance; 
}; 

struct Edge { 
    Vertex target; 
    int weight; 
}; 

typedef struct { 
    Vertex Nodes[20]; 
    int pass; 
    int infinity; 
} Graph; 

Ошибка дает это:

типа массив типа неполный элемент

Может кто-то пожалуйста, помогите мне понять, в чем проблема?

+0

-1 для размещения * снимка экрана * из текста. (Должно быть, это видео Youtube, показывающее ваш код по строкам, поддерживаемый Abba.) –

+0

@KerrekSB Проблема решена – totymedli

+2

Ваша установка не имеет смысла. Это по существу то же самое, что и 'struct Box {struct Box x; }; '. –

ответ

1
typedef struct Vertex Vertex; 
typedef struct Edge Vertex; 

это, вероятно, порождает конфликт имен, просто меняет имя одного из них.

+0

Нет, это не ответ. Нет конфликта имен. –

+0

В редактировании была только опечатка. Я исправил это, теперь, –

0

Единственный способ это будет возможно, использует смесь указателей и адресации, как вы реализуете ваши Vertex и Edge структуры:

/*your typedefs didn't make sense to me as it was conflicting. So, I edited it accordingly*/ 
//typedef struct Vertex Vertex; 
//typedef struct Edge Vertex; 

struct Vertex; 
struct Edge; 

typedef struct Vertex { 
    bool known; 
    char id[25]; 
    struct Edge *edges;//This HAS to be a pointer. 
    int distance; 
} Vertex; 

typedef struct Edge { 
    Vertex target; 
    int weight; 
} Edge; 

typedef struct { 
    Vertex Nodes[20]; 
    int pass; 
    int infinity; 
} Graph; 

Почему это работает? Из-за чего-то под названием forward declaration:

... вперед декларация является декларация идентификатора (обозначая объект, такие как тип, переменную или функцию), для которых программист еще не дали полное определение. Требуется для компилятор, чтобы узнать тип идентификатора (размер для памяти распределение, тип проверки типа, например подпись функций), , но не определенное значение, которое оно имеет (в случае переменных) или (в случае функций) ...

0

Может кто-то пожалуйста, помогите мне понять, в чем проблема?

Массивы обладают следующими свойствами:

  1. Все его элементы имеют одинаковый размер.
  2. Элементы хранятся смежно.

Это позволяет рассчитать адрес памяти каждого элемента (например, id[i]) от размера и адреса памяти первого элемента и индекса i.

Для этого компилятор должен знать, насколько велики элементы массива. Когда вы объявляете член Vertex::edges[20], компилятор пока не знает, как большие объекты типа Edge. Следовательно, ошибка компилятора.

Один из способов избежать этого - определить структуру Edge до структуры Vertex. В вашем случае это не поможет, потому что Edge::target имеет тип Vertex, и вы получите аналогичную ошибку. Адреса адресов элементов структуры вычисляются с использованием адреса памяти объекта и добавления размеров членов (и, возможно, некоторых дополнений), которые предшествуют запрашиваемому элементу.

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

0

В этой декларации

struct Vertex { 
    bool known; 
    char id[25]; 
    Edge edges[20]; 
    int distance; 
}; 

типа Edge пока не объявлена. Компилятор здесь знает только, что он будет соответствовать struct Edge, но сам struct не известен.

0

Подумайте об этом: компилятор должен знать размер структур вершин и краев. Если вы создаете Edge, Vertex и Vertex содержат Edge, он не сможет отсортировать размер. Решение состоит в том, чтобы указать только указатель на структуру (размер указателя должен быть известен компилятору). Я бы использовал версию jrd1 с небольшим изменением:

struct Edge { 
    struct Vertex* target; 
    int weight; 
} Edge; 

typedef struct Vertex { 
    bool known; 
    char id[25]; 
    struct Edge edges[20]; 
    int distance; 
} Vertex; 

typedef struct { 
    Vertex Nodes[20]; 
    int pass; 
    int infinity; 
} Graph; 

Это должно работать нормально.

Кроме того, если каждый край должен указывать Вершину, где она содержится, вам не нужно хранить этот указатель, вы можете использовать макрос container_of в ядре Linux, если хотите.

Смежные вопросы