Имея в своем распоряжении только функции GETCHAR иPUTCHAR вы можете, не зная ничего более об операциях вво-да-вывода, написать удивительное количество полезных прог-рамм. Простейшим примером может служить программа посимволь-ного копирования вводного файла в выводной. Общая схема име-ет вид:ввести символWHILE (символ не является признаком конца файла) вывести только что прочитанный символ ввести новый символ программа, написанная на языке "C", выглядит следующим обра-зом: MAIN() /* COPY INPUT TO OUTPUT; 1ST VERSION */ { INT C; C = GETCHAR(); WHILE (C != EOF) { PUTCHAR (C); C = GETCHAR(); } } оператор отношения != означает "не равно". Основная проблема заключается в том, чтобы зафиксиро-вать конец файла ввода. Обычно, когда функция GETCHAR натал-кивается на конец файла ввода, она возвращает значение , неявляющееся действительным символом; таким образом, программаможет установить, что файл ввода исчерпан. Единственное ос-ложнение, являющееся значительным неудобством, заключается всуществовании двух общеупотребительных соглашений о том, ка-кое значение фактически является признаком конца файла. Мыотсрочим решение этого вопроса, использовав символическоеимя EOF для этого значения, каким бы оно ни было. На практи-ке EOF будет либо -1, либо 0, так что для правильной работыперед программой должно стоять собственно либо #DEFINE EOF -1 либо #DEFINE EOF 0 Использовав символическую константу EOF для представле-ния значения, возвращаемого функцией GETCHAR при выходе наконец файла, мы обеспечили, что только одна величина в прог-рамме зависит от конкретного численного значения. Мы также описали переменную 'C' как INT , а не CHAR , стем чтобы она могла хранить значение, возвращаемое GETCHAR .как мы увидим в главе 2, эта величина действительно INT, таккак она должна быть в состоянии в дополнение ко всем возмож-ным символам представлять и EOF. Программистом, имеющим опыт работы на "C", программакопирования была бы написана более сжато. В языке "C" любоеприсваивание, такое как C = GETCHAR() может быть использовано в выражении; его значение - простозначение, присваиваемое левой части. Если присваивание сим-вола переменной 'C' поместить внутрь проверочной части опе-ратора WHILE , то программа копирования файла запишется ввиде: MAIN() /* COPY INPUT TO OUTPUT; 2ND VERSION */{INT C; WHILE ((C = GETCHAR()) != EOF)PUTCHAR(C);} Программа извлекает символ , присваивает его переменной'C' и затем проверяет, не является ли этот символ признакомконца файла. Если нет - выполняется тело оператора WHILE,выводящее этот символ. Затем цикл WHILE повторяется. когда,наконец, будет достигнут конец файла ввода, оператор WHILEзавершается, а вместе с ним заканчивается выполнение и функ-ции MAIN . В этой версии централизуется ввод - в программе толькоодно обращение к функции GETCHAR - и ужимается программа.Вложение присваивания в проверяемое условие - это одно изтех мест языка "C", которое приводит к значительному сокра-щению программ. Однако, на этом пути можно увлечься и начатьписать недоступные для понимания программы. Эту тенденцию мыбудем пытаться сдерживать. Важно понять , что круглые скобки вокруг присваивания вусловном выражении действительно необходимы. Старшинствооперации != выше, чем операции присваивания =, а это означа-ет, что в отсутствие круглых скобок проверка условия != бу-дет выполнена до присваивания =. Таким образом, оператор C = GETCHAR() != EOF эквивалентен оператору C = (GETCHAR() != EOF) Это, вопреки нашему желанию, приведет к тому, что 'C'будет принимать значение 0 или 1 в зависимости от того, на-толкнется или нет GETCHAR на признак конца файла. Подробнееоб этом будет сказано в главе 2/.