«Попробуй и посмотри» может рассказать вам, что что-то делает, но не то, что это предположительно.
В этом случае поведение цикла while
очевидно из кода: оно будет продолжаться до тех пор, пока getchar
не вернет значение 'y'
; он не остановится, когда getchar вернет '\n'
, или EOF
, или что-нибудь кроме 'y'
.
Для поведения самого getchar
, чтение с терминала, есть, по существу, три случая, чтобы волноваться о:
Если что-то было напечатано и еще не читал, getchar
возвращает следующий символ. getchar
сам по себе не заботится о границах линии; ENTER заставляет его возвращать '\n'
. Тем не менее, терминал (эмулятор) может подавать только файл в программу в целом, в зависимости от того, в каком режиме он находится, поэтому, если пользователь набрал abc
, но еще не ENTER, вы действительно можете находиться в состоянии 3 (см. Ниже).
Если терминал был закрыт (или псевдо-замкнут, набрав ^D) и все входные данные до этого момента была считана, getchar
будет возвращать EOF
, которое не равно любому значению символа. Он будет делать это снова и снова, пока приложение перестанет называть его. Ваш код buggy в том, что он не проверяет на EOF
: он будет застревать в цикле навсегда, если терминал будет закрыт. (Это может быть не очевидно при нормальной работе программы, поскольку закрытие терминала вызывает немедленную доставку сигнала SIGHUP
, который (по умолчанию) уничтожит этот процесс. Попробуйте запустить его как ./a.out < /dev/null
, чтобы увидеть бесконечный цикл.)
Если все, что было напечатано, было прочитано, но терминал все еще открыт, getchar
не вернется, пока не произойдет более типизация или терминал не будет закрыт. Базовый системный вызов read
называется блок, что означает, что ядро отбирает процессор от вашего процесса до тех пор, пока не станет доступным больше ввода (и позволяет другим программам выполнять: это не цикл спина, ожидающий ввода, как можно было бы предположить, если один был использован для kbhit
/getch
под DOS).
Вы пытаетесь запустить программу? – Ryan
@minitech, да, это работает. Зачем? – xdevel2000