Условие вычисляется, и если оно истинно, выполняется тело цикла (в нашем случае это одно обращение к printf). Затем осуществляется приращение шага:
fahr = fahr + 20
и условие вычисляется снова. Цикл заканчивается, когда условие становится ложным. Как и в случае с while, тело for-цикла может состоять из одной инструкции или из нескольких, заключенных в фигурные скобки. На месте этих трех выражений (инициализации, условия и приращения шага) могут стоять произвольные выражения.
Выбор между while и for определяется соображениями ясности программы. Цикл for более удобен в тех случаях, когда инициализация и приращение шага логически связаны друг с другом общей переменной и выражаются единичными инструкциями, поскольку названный цикл компактнее цикла while, а его управляющие части сосредоточены в одном месте.
Упражнение 1.5. Измените программу преобразования температур так, чтобы она печатала таблицу в обратном порядке, т. е. от 300 до 0.
1.4 Именованные константы
Прежде чем мы закончим рассмотрение программы преобразования температур, выскажем еще одно соображение. Очень плохо, когда по программе рассеяны "загадочные числа", такие как 300, 20. Тот, кто будет читать программу, не найдет в них и намека на то, что они собой представляют. Кроме того, их трудно заменить на другие каким-то систематическим способом. Одна из возможностей справиться с такими числами - дать им осмысленные имена. Строка #define определяет символьное имя, или именованную константу, для заданной строки символов:
#define имя подставляемый-текст
С этого момента при любом появлении имени (если только оно встречается не в тексте, заключенном в кавычки, и не является частью определения другого имени) оно будет заменяться на соответствующий ему подставляемый-текст. Имя имеет тот же вид, что и переменная: последовательность букв и цифр, начинающаяся с буквы. Подставляемый-текст может быть любой последовательностью символов, среди которых могут встречаться не только цифры.
#include ‹stdio.h›
#define LOWER 0 /* нижняя граница таблицы */
#define UPPER 300 /* верхняя граница */
#define STEP 20 /* размер шага */
/* печать таблицы температур по Фаренгейту и Цельсию */
main
{
int fahr;
for (fahr = LOWER; fahr ‹= UPPER; fahr = fahr + STEP)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
Величины LOWER, UPPER и STEP - именованные константы, а не переменные, поэтому для них нет объявлений. По общепринятому соглашению имена именованных констант набираются заглавными буквами, чтобы они отличались от обычных переменных, набираемых строчными. Заметим, что в конце #define-строки точка с запятой не ставится.
1.5 Ввод-вывод символов
Теперь мы намерены рассмотреть семейство программ по обработке текстов. Вы обнаружите, что многие существующие программы являются просто расширенными версиями обсуждаемых здесь прототипов.
Стандартная библиотека поддерживает очень простую модель ввода-вывода. Текстовый ввод-вывод вне зависимости от того, откуда он исходит или куда направляется, имеет дело с потоком символов. Текстовый поток - это последовательность символов, разбитая на строки, каждая из которых содержит нуль или более символов и завершается символом новой строки. Обязанность следить за тем, чтобы любой поток ввода-вывода отвечал этой модели, возложена на библиотеку: программист, пользуясь библиотекой, не должен заботиться о том, в каком виде строки представляются вне программы.
Стандартная библиотека включает несколько функций для чтения и записи одного символа. Простейшие из них - getchar и putchar. За одно обращение к getchar считывается следующий символ ввода из текстового потока, и этот символ выдается в качестве результата. Так, после выполнения
c = getchar;
переменная c содержит очередной символ ввода. Обычно символы поступают с клавиатуры. Ввод из файлов рассматривается в главе 7.
Обращение к putchar приводит к печати одного символа. Так,
putchar(c);
напечатает содержимое целой переменной c в виде символа (обычно на экране). Вызовы putchar и printf могут произвольным образом перемежаться. Вывод будет формироваться в том же порядке, что и обращения к этим функциям.
1.5.1 Копирование файла
При наличии функций getchar и putchar, ничего больше не зная о вводе-выводе, можно написать удивительно много полезных программ. Простейший пример - это программа, копирующая по одному символу с входного потока в выходной поток:
чтение символа