Partout où je vois "c'est pratiquement identique", ou quelque chose de similaire ...
De Le GNU Tutoriel de programmation C :
Il existe une autre fonction dans la bibliothèque GNU C appelée fgetc. Elle est identique à getc à bien des égards, sauf que getc est généralement implémentée en tant que fonction macro et est hautement optimisée, donc préférable dans la plupart des cas. (Dans les situations où vous lisez à partir d'une entrée standard, getc est à peu près aussi rapide que fgetc, car les humains tapent lentement par rapport à la vitesse à laquelle les ordinateurs peuvent lire leur entrée, mais lorsque vous lisez à partir d'un flux qui n'est pas produit de manière interactive par un humain, fgetc est probablement mieux.)
Quelles sont les autres différences? J'ai entendu dire qu'ils ont chacun une implémentation différente (et une peut être utilisée comme macro), mais qu'est-ce qui les rend si différents (ou suffisamment différents) pour qu'ils soient tous les deux dans la bibliothèque (ou spécification) Standard C?
Du Advanced Programming in Unix Environment
:
...
La différence entre
getc
etfgetc
est quegetc
peut être implémenté en tant que macro, tandis quefgetc
ne peut pas être implémenté en tant que macro. Cela signifie trois choses:
- L'argument de
getc
ne doit pas être une expression avec des effets secondaires.- Puisque
fgetc
est garanti d'être une fonction, nous pouvons prendre son adresse. Cela nous permet de passer l'adresse defgetc
comme argument à une autre fonction.- Les appels à fgetc prennent probablement plus de temps que les appels à
getc
, car cela prend généralement plus de temps pour appeler une fonction....
Il semble que les différences soient, dans 99,9% des cas, dénuées de sens.
Un point qui peut faire la différence - La page de manuel dit getc() may be implemented as a macro which evaluates stream more than once
.
Cela pourrait conduire à un comportement étrange dans certains cas (pas très utiles), par exemple:
FILE *my_files[10] = {...}, *f=&my_files[0];
for (i=0; i<10; i++) {
int c = getc(f++); // Parameter to getc has side effects!
}
Si getc
évalue f++
plus d'une fois, il avancera f
plus d'une fois par itération. En comparaison, fgetc
est sûr dans de telles situations.
Il y a essentiellement les mêmes (ou assez similaires pour ne pas déranger). Vous devriez regarder leur implémentation: GNU libc et MUSL libc sont des implémentations de logiciels libres. Et ils pourraient maintenant être implémentés en tant que fonctions en ligne (qui sont aussi rapides que des macros).
Et je ne dérangerai pas tant que ça. Dans la vie réelle, les E/S sont principalement limitées par le matériel (par exemple, le temps d'accès au disque).