web-dev-qa-db-fra.com

getc () vs fgetc () - Quelles sont les principales différences?

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?

45
Joe DF

Du Advanced Programming in Unix Environment:

...

La différence entre getc et fgetc est que getc peut être implémenté en tant que macro, tandis que fgetc 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 de fgetc 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.

...

42
mohit

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.

17
ugoren

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).

2