CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C] .h ou .c ?

Dkeagle
Dkeagle
Niveau 6
25 novembre 2018 à 13:30:33

Bonjour à tous,
Je débute dans la programmation en C (cours à l'école et cours sur OpenClassroom) et j'aimerais connaitre la différence entre les fichiers .h et les fichiers .c, parce que chaque cours que je suis les utilise de manière différente... Je m'explique:

Sur OpenClassroom, on apprends que les .h servent à mettre les prototypes de fonctions, les types de variables (structure) et autre petite choses, tandis que les .c sont là pour stocker les fonctions (dont les prototypes ont été mis dans le .h).

Hors, A l'école, pour un cours précis, le prof à du nous fournir une bibliotheque qu'il avait fait lui meme, et il s'agissait d'un fichier .h, en fouillant un peu j'ai remarqué qu'il avait TOUT mis dedans, fonctions, prototypes, structures... Il n'a utilisé AUCUN fichier .c, juste un .h

Du coup, quelle méthode est correcte ? Faut-il vraiment utiliser un .c ou est-il correct de s'en passer comme l'a fait mon prof ?

Merci d'avance pour vos réponses!

aAardvark
aAardvark
Niveau 75
25 novembre 2018 à 14:22:55

Je pense qu'il s'agit plutôt de convention de nommage - et je ne vois aucune de raison de ne pas le faire !

Mais en gros la directive #include "..." / <...> est tout simplement remplacée par le contenu du fichier qui est pointé, si tu veux savoir exactement comment ça marche. En gros avant la compilation le pré-processeur fait un traitement afin d'obtenir un ou plusieurs fichiers simples (les includes auront tous été remplacé), et qui je crois seront ensuite chacun compilés indépendamment en "fichier objet", avant que l'édition de liens ne se charge de lier le tout.

Mais pour que l'édition de liens se passe bien, il faut que que les déclarations de fonctions dans chacun des fichiers objets correspondent, et que chaque fonction soit bien définie dans un des fichiers objets. Sinon il y a erreur. De ce que je comprend de l'édition de liens c'est à peu près ça.

Le header s'occupe dont de contenir des bouts de code en commun, dans lesquels ont met les mêmes déclarations dont ont besoin plusieurs fichiers .c différents.

:d) http://www.equestionanswers.com/c/images/compilation-linking.gif (le linker devra normalement s'occuper d'autant de fichiers objet qu'il y a de fichier .c - plus les librairies additionnelles)

Après je te conseille de bien comprendre tout ce processus, c'est vraiment important pour être à l'aise et bien analyser les problèmes auquel tu seras confronté :oui:

Message édité le 25 novembre 2018 à 14:26:14 par aAardvark
Dkeagle
Dkeagle
Niveau 6
25 novembre 2018 à 15:29:41

aAardvark: Oui le fonctionnement des #include et du préprocesseur je l'avais bien compris grâce à OpenClassroom :D
En fait, ma question c'était surtout de savoir s'il y avait une méthode préférée à une autre ou si les deux se valent...

Parce que sur OpenClassroom ils disent de faire:

fonction.h:
Prototype de la fonction

fonction.c
Fonction en elle-meme

Et mon prof fait

fonction.h
Prototype de la fonction
Fonction en elle meme

pas de fonction.c

Du coup je vois pas la différence entre les deux, parce que le code final après le passage du préprocesseur sera exactement le même, mais au niveau des fichiers les méthodes sont différentes...

aAardvark
aAardvark
Niveau 75
25 novembre 2018 à 17:54:21

Du coup je vois pas la différence entre les deux, parce que le code final après le passage du préprocesseur sera exactement le même, mais au niveau des fichiers les méthodes sont différentes...

Après comme je te dis, ce ne sont que des conventions à ma connaissance, peu importe le .h ou le .c et les #include, ce qui compte c'est le fichier qui va être compilé à la fin, peu importe comment on s’organise avec le pré-processeur pour en arriver à ce fichier.

Mais ça ne veut pas dire qu'il n'y a pas des règles à respecter, la programmation demande de la rigueur, surtout pour pouvoir être compris par quelqu'un plus tard. Donc ne connaissant pas le niveau de ton prof, pose lui simplement la question. S'il ne donne pas de réponse satisfaisante, c'est qu'il a sans doute fait quelque chose qu'il ne fallait pas faire :hap:

Mais à ma connaissance un .h c'est un header, dans lequel on ne met logiquement que des déclarations diverses, pas de code ayant à être exécuté (quoique c'est peut-être accepté pour les fonctions inline faisant une seule ligne ?)

A la rigueur un fichier .c dans lequel on met tout car on a pas besoin d'un header (dans le cas d'un projet très très simple / exemple), ça ne me choque pas. Mais lui mettre une extension .h ça me paraît pas très logique.

Message édité le 25 novembre 2018 à 17:57:09 par aAardvark
godrik
godrik
Niveau 30
25 novembre 2018 à 18:21:38

C'est une question un peu complique qui demande a comprendre comment le C est compile.

Quand tu #include un fichier, ce fichier est essentiellement copier/coller dans celui qui l'inclut par le precompilateur. Ca veut dire que du point de vue du compilateur, il n'y a pas de difference entre ecrire la fonction dans le .h et ecrire la fonction dans chaque .c qui inclut le .h.

Quand tu defini une fonction, du genre: int f1(){return 12;}, tu indiques au compilateur que la fonction doit etre exporte dans la table des symboles.

Donc si tu defini la meme fonction plusieurs fois dans different .c (par exemple, par inclusion d'un .h) alos la emme fonction va etre exporte plusieurs fois dans la table des symbols et tu aura une erreur a l'edition de lien.

C'est pour ca qu'en general, la fonction est declare dans le .h par int f1(); mais pas defini. Ca indique au compilateur qu'il y a une fonction f1 dans la table des symboles contre la quelle il faut linker. Et c'est pour ca que l'on prefere en general declare les fonctions dans des .h et les definir dans un .c apart.

Quand le cadre de ton cours, j'imagine que vous n'utilisez pour l'instant que des codes en un seul fichier .c. Du coup ca peut etre plus simple de mettre la definition de la fonction dans le .h parceque ca ne causera pas de probleme et comme ca, ca rend la configuration de la chaine de compilation plus simple parcequ'on peut faire compilation et linkage en un seul coup.

Deux cas particuliers, les fonctions inline et static ne sont pas exporte dans la table des symboles. C'est bien parcequ'on peut tout mettre dans le .h. C'est pas bien parceque ca veut dire que chaque fichier va avoir sa propre copie de toutes les fonctions et ca fait grossir la taille du binaire.

En C++ (je sais c'est un question de C, mais la question est interessante en C++), les templates ont aussi un comportement particulier relativement a la table des symboles. Et typiquement le code entier des fonctions est dans les .h. Ca permet de faire des "templates only library" qui n'ont pas besoin de linker contre quoi que ce soit, amis qui ont un cout de compilation plus eleve. Typiquement, la plus par de la lib boost est ecrite comme ca.

Dkeagle
Dkeagle
Niveau 6
25 novembre 2018 à 18:28:15

D'accord, merci beaucoup à vous deux pour vos réponses!
Comme la conseillé aAadvard, j'irais demander au prof la raison de l'utilisation d'un seul fichier .h ^^
Maintenant, j'imagine grâce à vos explications qu'il a fait ça simplement pour gagner du temps dans la compilation en nous évitant de devoir passer par un .c en plus ^^

GSX-R
GSX-R
Niveau 36
25 novembre 2018 à 23:03:48

C’est un poil trop rapide comme généralité de dire que

Prototype de fonction = h
Définition de fonction = c

Ça dépend surtout de ce qu’on souhaite faire.
Déjà d’office si la fonction est utilisée uniquement dans le cadre de ce fichier c, on la déclare dans ce même fichier c.

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware