Язык Си - руководство для начинающих
Шрифт:
В среде ОС UNIX диалог будет выглядеть следующим образом:
% sketcher
B 10 20
BBBBBBBBBBB
Y 12 18
YYYYYYY
[CTRL/-d]
%
/* художник-график */
/* РИСУЕТ сплошные фигуры */
#include
#define MAXLENGTH 80
main
{
int ch; /*печатаемыйсимвол*/
int start, stop; /*
int count; /* счетчикпозиций*/
whilе((сh = getchar) != EOF) /* вводсимвола*/
{
if(ch != '\n' ) /*пропуск символа "новая строка"*/
{ scanf(" %d %d", &start, &stop); /* ввод граничных значний*/
if (start > stop || start < 1 || stop > MAXLENGTH)
printf(" Введены неправильные граничные значе ния \n");
else
{ count = 0;
while(++count < start)
putchar(' '); /* печать пробелов вплоть до начальной позиции */
while(count++ <= stop)
putchar(ch); /*печать символа до конечной позиции */
putchar(' \n'); /* закончить печать строки и начать новую */
} /* конец части else */
} /* конец проверки содержимого ch */
} /* конец цикла while */
} /* конец программы */
РИС. 7. 5. Программа, рисующая символами
Программа вывела на экран символ В в позициях с 10 по 20, а символ Y– с 12 по 18. К сожалению, при диалоговой работе с программой на экране наши команды перемежаются выводимым строками. Гораздо более удобным способом использования программы является создание файла, содержащего подходящий набор данных, а затем применение операции переключения для ввода (из него) параметров в программу. Предположим, например, что в файле с именем fig содержатся следующие данные:
– 30 50
| 30 50
| 30 50
| 30 50
| 30 50
| 30 50
= 20 60
: 31 49
: 31 49
: 29 49
: 27 49
: 25 49
: 30 49
: 30 49
/ 30 49
: 35 48
: 35 48
Послe ввода команды sketcher < fig результат работы программы будет выглядеть так, как показано на рис. 7.6.
Анализ программы
Длина строки
Структура программы
В нашей программе имеются три цикла while, один оператор if и
while((ch = getchar) != EOF)
Задачей первого цикла while является ввод нескольких наборов данных. (Каждый набор данных состоит из символа и двух целых чисел, указывающих границы его вывода). Производя вначале чтение символа, мы смогли объединить в одном выражении его ввод и проверку того, не является ли он признаком EOF. Если прочитан символ EOF, то программа останавливается, не делая попытки ввести величины, соответствующие переменным start и stop. В противном случае при помощи функци scanf указанным переменным присваиваются введенные значения, затем программа переходит к их обработке. Этим завершается выполнение тела цикла, после чего вводится новый символ, и весь процесс повторяется снова.
Обратите внимание, что для чтения данных мы использовали два оператора, а не один. Почему нельзя было воспользоваться одним оператором?
scanf(" %с %D %D", &ch, &start, &stop)
Предположим, мы это сделали. Рассмотрим, что происходит, когда программа заканчивает чтение последнего набора данных из файла. Перед началом выполнения очередного тела цикла единственным оставшимся непрочитанным элементом файла будет признак EOF. Функция scanf читает указанный символ и присваивает его переменной ch; зaтем oна пытается ввести значение для переменной start, но в файле не осталось данных, которые не были бы уже прочитаны! Компьютер выскажет свое недовольство, и ваша программа прекратит работу. Отделяя чтение символа от ввода остальных данных, мы позволяем компьютеру обнаружить появление признака EOF перед очередной попыткой прочесть оставшиеся данные.
if (ch != '\n')
Цель введения в программу первого оператора if состоит в том, чтобы упростить чтение данных. Мы объясним, как он работает в следующем разделе.
if(start > stop || start < 1 || stop > MAXLENGTH) printf(" Введены неправильные граничные значения \n");else
Цель применения оператора if-else состоит в том, чтобы избежать использования в программе таких значении переменных start и stop, которые могут привести к нежелательным последствиям. Этот вопрос мы также обсудим ниже. Обратите, однако, внимание на то, как мы использовали логические операции и операции отношения, чтобы обнаружить появление любого из трех "опасных" значений.
Основная часть программы представляет собой составной оператор, который следует за ключевым словом else.
count = 0;
Вначале счетчик count устанавливается на нуль.
while(++count < start) putchar(' ');
Затем в цикле while начинается вывод на печать пробелов вплоть до позиции, определяемой значением переменной start. Ecли значение start, скажем, равно 10, то печатается девять пробелов. Поэтому вывод символов на печать начнется с 10-й позиции. Обратите внимание, как использование префиксной формы операции увеличения вместе с операцией < позволяет добиться указанного эффекта. Если бы вместо этого мы использовали выражение count++ < start, то сравнение проводилось бы перед увеличением значения count, и в результате мог быть напечатан один дополнительный пробел.