#include <stdio.h>
#include <stdlib.h>
typedef struct sommet sommet;
typedef struct voisin voisin;
typedef struct graphe graphe;
struct sommet{
int indice;
sommet* next;
voisin* first_voisin;
};
struct voisin{
int indice;
voisin* next_voisin;
};
struct graphe{
sommet* premier_sommet;
};
Вот простая программа определения структуры h. Я получаю сообщение об ошибке: переопределение структуры для каждого из них. Как я могу это исправить ? Спасибо !
Я попробовал поставить напрямую
typedef struct sommet {
//code
};
а также
typedef struct{
//code
}sommet;
Как используется этот заголовок? У вас есть несколько файлов заголовков (.h) и исходных файлов (.c)?
Убедитесь, что у вас есть включающая охрана
Примечание: не используйте #include <stdio.h> и #include <stdlib.h> в заголовочном файле, если вам не нужно что-либо из этих заголовочных файлов в вашем заголовочном файле. Судя по всему, нет.
Привет! Это сообщение об ошибке сообщает вам, что после определения структуры типа sommet вы можете в любое время снова упомянуть имя структуры, но не сможете повторно определить ее где-либо еще. Под «определить» мы имеем в виду показать это, назвав все компоненты/члены, как вы это сделали в самый первый раз. Именно поэтому Бармар упоминает защиту включения — потому что каждый модуль, включающий файл *.h с определением структуры, рискует переопределить структуру — но защита включения гарантирует, что он определен только один раз. Лучше всего (не обязательно) объявлять typedef с первого раза, когда вы определяете структуру.





Высока уверенность в том, что вы сможете решить проблемы, возникающие во время компиляции переопределения, следуя лучшим практикам, таким как следующие... обратите внимание, что этот код представляет 2 файла — MyHeaderFile.h и main.c.
Защита включения MY_HEADER_FILE_H в верхней части MyHeaderFile.h гарантирует, что определения структуры (и все остальное во включаемом файле) будут определены только один раз, и это ключевой момент. Он сообщает компилятору: «Входите после этой точки, только если MY_HEADER_FILE_H НЕ определен». Это предотвращает второе определение всего последующего.
Помимо этого больше рассказывать нечего — в конце концов, это ваш код.
Работоспособный код здесь.
/* ---------- MyHeaderFile.h ---------- */
#ifndef MY_HEADER_FILE_H
#define MY_HEADER_FILE_H
#include <stdio.h> /* Pls see Ted Lyngmo's comment on this */
#include <stdlib.h>
typedef struct sommet sommet;
typedef struct voisin voisin;
typedef struct graphe graphe;
struct sommet{
int indice;
sommet* next;
voisin* first_voisin;
};
struct voisin{
int indice;
voisin* next_voisin;
};
struct graphe{
sommet* premier_sommet;
};
#endif //MY_HEADER_FILE_H
/* ---------- main.c ---------- */
#include "MyHeaderFile.h"
int main()
{
voisin v = {5, NULL};
printf("%d\n", v.indice);
return 0;
}
Выход:
5
Кажется, ваша проблема описана @greg.
В любом случае, это правильный синтаксис:
// I define a named struct, and then a type based on it
struct sommet {
int indice;
};
typedef struct sommet t_sommet;
Это также допустимый синтаксис:
// I define a named struct and a type (at the same time)
typedef struct sommet {
int indice; // etc
} t_sommet;
Это также допустимый синтаксис:
// I directly define a type, based on an unnamed struct
typedef struct {
int indice; // etc
} t_sommet;
Во всех случаях я использую sommet как имя структуры и t_sommet как имя (псевдо) нового типа, за исключением последнего примера, где я не называю структуру. Использование одного и того же имени для структуры И для типа, как вы это сделали, вполне допустимо, но как-то сбивает с толку, по крайней мере, для меня. На самом деле вам не нужно определять и то, и другое: достаточно имени структуры или typedef. В зависимости от вашего выбора вы позже будете ссылаться на структуру (или тип), используя любой из этих вариантов:
struct sommet one; // I'm using the struct name here (the struct keyword is required)
t_sommet another; // I'm using the type name here
Это НЕдопустимый синтаксис (имя нового типа отсутствует):
typedef struct sommet {
int indice; // etc
};
То, что вы показали, это нормально. Проблема в коде, который вы не показали. Пожалуйста, обновите свой вопрос, включив в него минимально воспроизводимый пример. При этом мой хрустальный шар говорит, что вы включаете файл более одного раза в данный исходный файл.