Язык Си - руководство для начинающих
Шрифт:
/*ввод-вывод2 */
/*ввод и печать символов до поступления завершающего символа*/
#include
#define STOP * /*дает символу * символическое имя STOP*/
main
{
char ch;
ch = getchar; /* строка 9 */
while(ch!= STOP){ /* строка 10 /
putchar (ch); / * строка 11 */
ch=getchar ; / *
}
}
В данном примере была использована структура программы, обсуждавшаяся нами в конце гл. 5 (вопрос 3). При первом прохождении тела цикла функция putchar получает значение своего аргумента в результате выполнения оператора, расположенного в строке 9; в дальнейшем, вплоть до завершения работы цикла, значением этого аргумента является символ, передаваемый программе функцией getchar, расположенной в строке 12. Мы ввели новую операцию отношения !=, смысл которой выражается словами "не равно". В результате всего этого цикл while будет осуществлять чтение и печать символов до тех пор, пока не поступит признак STOP. Мы могли бы опустить в программе директиву #define и использовать лишь символ * в операторе while, но наш способ делает смысл данного знака более очевидным.
Перед тем как приступить к выполнению этой замечательной программы на своей машине, взгляните на ее следующий вариант. Программа, приведенная ниже, делает то же самое, но стиль ее написания лучше отвечает духу языка Си:
/* ввод-выводЗ */
#include
#define STOP *
main
{
char ch;
while ((ch=getchar) != STOP) /* строка 8 */
putchar (ch);
}
Одна строка 8 этой программы заменяет строки 9, 10 и 12 программы ввод-вывод2. Как же работает этот оператор? Начнем с того, что рассмотрим содержимое внутренних скобок:
ch = getchar
Это - выражение. Его смысл заключается в вызове функции getchar и присваивании полученного значения переменной ch. Одним таким действием мы выполним то, чему в программе ввод-вывод2 были посвящены строки 9 и 12. Далее напомним, что любое выражение имеет значение и что значение выражения, включающего в себя операцию присваивания, совпадает со значением переменной, расположенной слева от знака = . Следовательно, значение выражения (ch = getchar)– это величина переменной ch, так что
(ch = getchar) ! = STOP
имеет то же действие, что и
ch != STOP
Тем самым выполняется проверка, которую в программе ввод-вывод2 осуществлял оператор, расположенный в строке 10. Конструкции подобного сорта (объединение в одном выражении операций присваивания и сравнения) довольно часто используются при программировании на языке Си:
Теперь вернемся к нашей программе и попробуем ее выполнить. Если в вашей системе реализован небуферизованный ввод, результат может выглядеть, например, следующим образом:
ИИннттеерреесснноо ppаaббooттaаеeтт ллии ооннаа . Думаю что да.
При вводе все символы вплоть до признака STOP (звездочка), медленно отображаются на экране (эхо-печать). Дублируются даже пробелы. Однако, как только вы ввели признак STOP, работа программы прекращается и все, что вы набираете на пульте после этого, появляется на экране без эхо-дублирования.
Теперь посмотрим, что будет происходить в системе, обладающей буферизованным вводом. В этом случае программа не начнет работать до тех пор, пока вы не нажмете на клавишу [ввод]. Вот пример возможного диалога
Интересно, работает ли она. Гм , не знаю [ввод].
Интересно, работает ли она.
Первая строка была целиком передана программе. Программа последовательно читает эту строку по одному символу и также по одному символу выводит на печать до тех пор, пока не встретит символ *.
Теперь напишем несколько более полезную программу. Мы заставим ее подсчитывать символы, которые она читает. Нам требуется для этого ввести в предыдущую программу лишь некоторые изменения
/* подсчет символов! */
#define STOP *
main
{
char ch;
int count =0; /* инициализация счетчика символов 0 */
while ((ch = getchar)!= STOP)
{
putchar (ch);
count++; /* прибавить 1 к счетчику */
}
printf (" \n Всего было прочитано %d символов \n ' , count);
}
Чтение одной строки
Давайте подумаем, какие дополнительные усовершенствования можно ввести в программу, используя только те средства, которыми мы владеем. Первое, что легко можно сделать - это заменить признак окончания ввода данных. Но можно ли предложить что-то лучшее, чем символ *? Одной из возможностей является использование символа "нова строка" (\n). Для этого нужно лишь переопределить признак STOP.
#define STOP ' \n '
Какой это даст эффект? Очень большой ведь символ "новая стрoка" пересылается при нажатии клавиши [ввод], следовательно, в результате наша программа будет обрабатывать одну вводимую строку. Предположим, например, что мы внесли указанное изменение в программу подсчет символов1, а затем при ее выполнении ввели следующую строку:
О! Быть сейчас во Фресно, когда здесь лето, [ввод]
В ответ на экране появятся следующие строки