Получение ошибки: переопределение структуры в программе .h

#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;

То, что вы показали, это нормально. Проблема в коде, который вы не показали. Пожалуйста, обновите свой вопрос, включив в него минимально воспроизводимый пример. При этом мой хрустальный шар говорит, что вы включаете файл более одного раза в данный исходный файл.

dbush 10.04.2024 19:57

Как используется этот заголовок? У вас есть несколько файлов заголовков (.h) и исходных файлов (.c)?

Mathieu 10.04.2024 19:57

Убедитесь, что у вас есть включающая охрана

Barmar 10.04.2024 20:00

Примечание: не используйте #include <stdio.h> и #include <stdlib.h> в заголовочном файле, если вам не нужно что-либо из этих заголовочных файлов в вашем заголовочном файле. Судя по всему, нет.

Ted Lyngmo 10.04.2024 20:42

Привет! Это сообщение об ошибке сообщает вам, что после определения структуры типа sommet вы можете в любое время снова упомянуть имя структуры, но не сможете повторно определить ее где-либо еще. Под «определить» мы имеем в виду показать это, назвав все компоненты/члены, как вы это сделали в самый первый раз. Именно поэтому Бармар упоминает защиту включения — потому что каждый модуль, включающий файл *.h с определением структуры, рискует переопределить структуру — но защита включения гарантирует, что он определен только один раз. Лучше всего (не обязательно) объявлять typedef с первого раза, когда вы определяете структуру.

greg spears 10.04.2024 20:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Высока уверенность в том, что вы сможете решить проблемы, возникающие во время компиляции переопределения, следуя лучшим практикам, таким как следующие... обратите внимание, что этот код представляет 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
};

Другие вопросы по теме

Похожие вопросы