getc () vs fgetc () - в чем основные различия?
везде, где я вижу "это практически идентично", или что-то подобное...
с учебник по программированию GNU C :
в библиотеке GNU C есть еще одна функция, называемая fgetc. Он идентичен getc во многих отношениях, за исключением того, что getc обычно реализуется как макрофункция и сильно оптимизирован, поэтому предпочтительнее в большинстве ситуаций. (В ситуациях, когда вы читаете со стандартного ввода, getc примерно так же быстро, как fgetc, поскольку люди печатают медленно по сравнению с тем, как быстро компьютеры могут читать их ввод, но когда вы читаете из потока, который не интерактивно производится человеком, fgetc, вероятно, лучше.)
каковы другие различия? Я слышал, что у каждого из них есть другая реализация (и ее можно использовать как макрос), но что делает их настолько разными (или достаточно разными), чтобы они были в стандартной библиотеке C (или спецификации)?
3 ответов
С Advanced Programming in Unix Environment
:
...
разницу между
getc
иfgetc
этоgetc
может быть реализован как макрос, тогда какfgetc
не может быть реализован как макрос. Это означает три вещи:--10-->
- аргумент
getc
не должно быть выражением с побочными эффектами.- С
fgetc
гарантированно будет функцией, мы можем взять ее адрес. Это позволяет нам передать адресfgetc
в качестве аргумента другой функции.- вызовы fgetc, вероятно, занимают больше времени, чем вызовы
getc
, так как обычно требуется больше времени для вызова функции....
похоже, что различия в 99,9% случаев бессмысленны.
один момент, который может иметь значение - man page говорит getc() may be implemented as a macro which evaluates stream more than once
.
это может привести к странному поведению в некоторых (не очень полезно) случаях, например:
FILE *my_files[10] = {...}, *f=&my_files[0];
for (i=0; i<10; i++) {
int c = getc(f++); // Parameter to getc has side effects!
}
если getc
оценивает f++
более одного раза, он будет продвигать f
более одного раза за итерацию. Для сравнения,fgetc
безопасно в таких ситуациях.
есть по существу то же самое (или достаточно похожее, чтобы не беспокоиться). Вы должны посмотреть на их реализацию:GNU libc и MUSL библиотеки libc являются реализациями свободного программного обеспечения. И теперь они могут быть реализованы как встроенные функции (которые так же быстры, как макросы).
и я не буду так сильно беспокоиться. В реальной жизни ввод-вывод в основном ограничен оборудованием (например, временем доступа к диску).