Это сломанная функция, написанная кем-то, кто считал себя умным.
Объекты buf
, L
и R
определены с static
, они существуют в течение всего временивыполнения программы и инициализируются, когда начинается выполнение.Они сохраняют свои значения между вызовами функции.
Номинально функция возвращает либо символ (*L++
), либо EOF
.Но тип возвращаемого значения - char
, который не должен использоваться подпрограммами, возвращающими EOF
.EOF
задано как значение int
и либо не является значением char
, перекрывает значение char
(что нежелательно, поскольку в этом случае их невозможно различить - процедура должна использовать unsigned char
для buf
) или вызывает другие проблемы при преобразовании в значение char
(преобразование будет сигнализировать или будет перекрываться со значением char
).
Намерение, по-видимому, такое: L
(для «Слева ») указывает на левую сторону символов, которые были считаны в буфер и еще не использованы, а R
указывает на правую сторону (конец) символов, которые были считаны в буфер.Когда L
равно R
, буфер пуст, и в него следует читать больше символов.
Когда L
(для «левого») и R
(для «правого»)равно, правый операнд &&
оценивается.Мы можем переписать его:
(R = (L=buf) + fread(buf,1,100000,stdin), L==R)
? EOF
: *L++;
Это сбрасывает L
в начало буфера и затем пытается прочитать 10000 символов.Количество фактически прочитанных символов добавляется к L
, а затем присваивается R
.Так L
указывает на начало вновь прочитанных символов (в начале buf
), а R
указывает на конец (один после последнего прочитанного символа).
После этого,Оператор запятой эффективно заставляет L==R
использоваться в качестве управляющего значения для ? :
.Если никакие символы не были прочитаны, L
равняется R
, и процедура пытается вернуть EOF
(но может потерпеть неудачу, как объяснено выше).Если символы были прочитаны, *L++
возвращает первый символ и увеличивает L
для указания следующего символа.
При последующих вызовах, когда в буфере есть символы, левый операнд &&
,L==R
, ложно, поэтому правый операнд не оценивается.Тогда выражение выглядит как false && (DoesNotMatter) ? EOF : *L++
.Поскольку результат &&
равен false, *L++
возвращает следующий символ в буфере и увеличивает L
.Поскольку вызовы продолжаются, в конечном итоге L
будет равняться R
, и буфер будет пуст, что приведет к чтению новых данных.