Si tu codes un module, avec exemple.h et exemple.c par exemple, avec dans exemple.c ton implementation, et dans exemple.h tes prototypes, alors moi j'ai pour habitude de mettre tous les includes nécessaires dans exemple.h, et ensuite j'include exemple.h dans exemple.c, comme ça, je réparti pas tout partout, je vois tout ce que j'ai inclus et utilisé pour mon module en regardant juste le contenu de mon exemple.h
mais sinon mettre ça dans les deux je crois que c'est inutile, ça ne changera pas grand chose concrétement, puisque que stdio.h stdlib.h unistd.h math.h etc etc ont du #ifndef _CONSTANTE_ pour éviter que le préprocesseur inclus plusieurs fois la même chose de toute façon, donc le fait de ne pas écrire ça plusieurs fois te fais gagner une vérification durant l'étape juste avant la compilation pour chaque doublon, triplon, quadruplon etc..,
En fait, je pense que le fait de ne pas rajouter ça partout c'est surtout pour un soucis de "lisibilité" et de "propreté" je dirais, enfin je vois ça comme ça
en bref le fait de faire ses inclusions dans le .c ou dans le .h, c'est selon le contexte, puis aussi selon comment toi tu trouves ça plus ou moins propre, sauf si t'es dans un cas d'inclusion circulaire (par forcement direct, ça peut être indirectement) et dans ce cas faudra placer les includes de façon plus précise, comme en C++ avec la définition des classes lorsqu'elles s'utilisent de façon mutuelle, mais bon ça peut arriver en C avec définition de structure je pense