Tout est dans le titre. Je pense que c'est très simple, mais il est si difficile de chercher des choses syntaxiques n'importe où.
Ce sont deux fichiers de bibliothèque que je copie/ CS50.net , et je me demande pourquoi ils ont deux extensions différentes.
Fichier .c: c (où l'action réelle est, en général)
.h: fichier d’en-tête (à inclure dans une directive __ pré-processeur #include
). Contient des éléments qui sont normalement réputés être partagés avec d'autres parties de votre code, tels que les prototypes de fonctions, les éléments # define, la déclaration externe pour les variables globales (oh, l'horreur), etc.
Techniquement, vous pouvez tout mettre dans un seul fichier. Tout un programme en C. millions de lignes. Mais nous, les humains, avons tendance à organiser les choses. Vous créez donc différents fichiers C, chacun contenant des fonctions particulières. C'est tout gentil et propre. Puis tout à coup, vous vous rendez compte que la déclaration que vous avez dans un fichier C donné devrait également exister dans un autre fichier C. Donc, vous les dupliqueriez. Le mieux est donc d'extraire la déclaration et de la placer dans un fichier commun, le .h
Par exemple, dans le fichier cs50.h, vous trouverez ce que l’on appelle des "déclarations en aval" de vos fonctions . Une déclaration en aval est un moyen rapide de dire au compilateur comment une fonction doit être appelée (par exemple, quels paramètres d’entrée) et ce qu’elle renvoie, afin qu'il puisse effectuer le contrôle approprié (par exemple, si vous appelez une fonction avec un nombre incorrect de paramètres, il se plaindra).
Un autre exemple. Supposons que vous écriviez un fichier .c contenant une fonction effectuant une correspondance d'expression régulière. Vous voulez que votre fonction accepte l'expression régulière, la chaîne à faire correspondre et un paramètre indiquant si la comparaison doit être sensible à la casse.
dans le .c vous allez donc mettre
bool matches(string regexp, string s, int flags) { the code }
Maintenant, supposons que vous souhaitiez passer les drapeaux suivants:
0: si la recherche est sensible à la casse
1: si la recherche est insensible à la casse
Et vous voulez rester ouvert à de nouveaux drapeaux, vous n'avez donc pas mis de booléen . Il est difficile de jouer avec des nombres, vous devez donc définir des noms utiles pour ces drapeaux.
#define MATCH_CASE_SENSITIVE 0
#define MATCH_CASE_INSENSITIVE 1
Cette information va dans le .h, car si un programme veut utiliser ces étiquettes, il n’a aucun moyen de les connaître à moins d’inclure l’information. Bien sûr, vous pouvez les mettre dans le fichier .c, mais vous devrez alors inclure le code .c (entier!), Ce qui est une perte de temps et une source de problèmes.
Bien entendu, rien n'indique que l'extension d'un fichier d'en-tête doit être .h
et que l'extension d'un fichier source C doit être .c
. Ce sont des conventions utiles.
E:\Temp> type my.interface
#ifndef MY_INTERFACE_INCLUDED
#define MYBUFFERSIZE 8
#define MY_INTERFACE_INCLUDED
#endif
E:\Temp> type my.source
#include <stdio.h>
#include "my.interface"
int main(void) {
char x[MYBUFFERSIZE] = {0};
x[0] = 'a';
puts(x);
return 0;
}
E:\Temp> gcc -x c my.source -o my.exe
E:\Temp> my
a
Ce ne sont pas vraiment des fichiers de bibliothèque. Ce ne sont que des fichiers sources. Comme Stefano l’a dit, le fichier .c est le fichier source C qui utilise réellement/définit la source réelle de ce qu’il a simplement décrit dans le fichier .h , le fichier d’en-tête. Le fichier d'en-tête décrit généralement tous les prototypes et structures de fonction qui seront utilisés dans le fichier source réel. Pensez-y comme une référence/annexe. C’est évident lorsque vous regardez le fichier d’en-tête, comme vous le verrez :) Ainsi, lorsque vous souhaitez utiliser quelque chose qui a été écrit dans ces fichiers source, vous #include
le fichier d’en-tête, qui contient les informations que le compilateur doit connaître.
Le .c est le fichier source et .h le fichier en-tête .
Les fichiers .c sont des fichiers source qui seront compilés. Les fichiers .h sont utilisés pour exposer l'API d'un programme à une autre partie de ce programme ou à un autre programme en cours de création d'une bibliothèque.
Par exemple, le programme PizzaDelivery pourrait comporter 1 fichier .c avec le programme principal et 1 fichier .c avec fonctions utilitaires. Maintenant, pour que la partie principale du programme puisse utiliser les fonctions utilitaires, vous devez exposer l'API, via un prototype de fonction, dans un fichier .h, ce fichier .h étant inclus dans le fichier .c principal.
.c : 'C' source code
.h : Header file
Habituellement, les fichiers .c
contiennent l'implémentation et les fichiers .h
contiennent "l'interface" d'une implémentation.