Переменные и арифметика
Следующая программа печатает приведенную ниже таблицу температур по Фаренгейту и их эквивалентов по стоградусной шкале Цельсия, используя для перевода формулу
c = (5/9)*(f-32). 0 -17.8 20 -6.7 40 4.4 60 15.6 ... ... 260 126.7 280 137.8 300 140.9
Теперь сама программа:
/* print fahrenheit-celsius table for f = 0, 20, ..., 300 */ main() { int lower, upper, step; float fahr, celsius; lower = 0; /* lower limit of temperature table */ upper =300; /* upper limit */ step = 20; /* step size */ fahr = lower; while (fahr <= upper) { celsius = (5.0/9.0) * (fahr -32.0); printf("%4.0f %6.1f\n", fahr, celsius); fahr = fahr + step; } }
Первые две строки
/* print fahrenheit-celsius table for f = 0, 20, ..., 300 */
являются комментарием, который в данном случае кратко поясняет, что делает программа. Любые символы между /* и */ игнорируются компилятором; можно свободно пользоваться комментариями для облегчения понимания программы. Комментарии могут появляться в любом месте, где возможен пробел или переход на новую строку.
В языке "C" все переменные должны быть описаны до их использования, обычно это делается в начале функции до первого выполняемого оператора. Если вы забудете вставить описание, то получите диагностическое сообщение от компилятора. описание состоит из типа и списка переменных, имеющих этот тип, как в
int lower, upper, step; float fahr, celsius;
тип int означает, что все переменные списка целые; тип float предназначен для чисел с плавающей точкой, т.е. для чисел, которые могут иметь дробную часть. Точность как int, так и float зависит от конкретной машины, на которой вы работаете. На PDP-11, например, тип int соответствует 16-битовому числу со знаком, т.е. числу, лежащему между -32768 и +32767. Число типа float - это 32-битовое число, имеющее около семи значащих цифр и лежащее в диапазоне от 10е-38 до 10е+38. В лекции № 2 приводится список размеров для других машин.
В языке "C" предусмотрено несколько других основных типов данных, кроме int и float:
char | символ - один байт |
short | короткое целое |
long | длинное целое |
double | плавающее с двойной точностью |
Размеры этих объектов тоже машинно-независимы; детали приведены в лекции № 2. Имеются также массивы, структуры и объединения этих основных типов, указатели на них и функции,которые их возвращают; со всеми ними мы встретимся в свое время.
Фактически вычисления в программе перевода температур начинаются с операторов присваивания
lower = 0; upper =300; step = 20; fahr =lower;
которые придают переменным их начальные значения. каждый отдельный оператор заканчивается точкой с запятой.
Каждая строка таблицы вычисляется одинаковым образом, так что мы используем цикл, повторяющийся один раз на строку. В этом назначение оператора while:
while (fahr <= upper) { .... }
проверяется условие в круглых скобках. Если оно истинно (fahr меньше или равно upper ), то выполняется тело цикла (все операторы, заключенные в фигурные скобки { и }). Затем вновь проверяется это условие и, если оно истинно, опять выполняется тело цикла. Если же условие не выполняется (fahr превосходит upper), цикл заканчивается и происходит переход к выполнению оператора, следующего за оператором цикла. Так как в настоящей программе нет никаких последующих операторов, то выполнение программы завершается.
Тело оператора while может состоять из одного или более операторов, заключенных в фигурные скобки, как в программе перевода температур, или из одного оператора без скобок, как, например, в
while (i<j) i = 2 * i;
В обоих случаях операторы, управляемые оператором while, сдвинуты на одну табуляцию, чтобы вы могли с первого взгляда видеть, какие операторы находятся внутри цикла. Такой сдвиг подчеркивает логическую структуру программы. Хотя в языке "C" допускается совершенно произвольное расположение операторов в строке, подходящий сдвиг и использование пробелов значительно облегчают чтение программ. Мы рекомендуем писать только один оператор на строке и (обычно) оставлять пробелы вокруг операторов. Расположение фигурных скобок менее существенно; мы выбрали один из нескольких популярных стилей. Выберите подходящий для вас стиль и затем используйте его последовательно.
Основная часть работы выполняется в теле цикла. Температура по Цельсию вычисляется и присваивается переменной celsius оператором
celsius = (5.0/9.0) * (fahr-32.0);
причина использования выражения 5.0/9.0 вместо выглядящего проще 5/9 заключается в том, что в языке "C", как и во многих других языках, при делении целых происходит усечение, состоящее в отбрасывании дробной части результата. Таким образом, результат операции 5/9 равен нулю, и, конечно, в этом случае все температуры оказались бы равными нулю. Десятичная точка в константе указывает, что она имеет тип с плавающей точкой, так что, как мы и хотели, 5.0/9.0 равно 0.5555....
Мы также писали 32.0 вместо 32, несмотря на то, что так как переменная fahr имеет тип float, целое 32 автоматически бы преобразовалось к типу float (в 32.0) перед вычитанием. С точки зрения стиля разумно писать плавающие константы с явной десятичной точкой даже тогда, когда они имеют целые значения; это подчеркивает их плавающую природу для просматривающего программу и обеспечивает то, что компилятор будет смотреть на вещи так же, как и Вы.
Подробные правила о том, в каком случае целые преобразуются к типу с плавающей точкой, приведены в лекции № 2. Сейчас же отметим, что присваивание
fahr = lower;
проверка
while (fahr <= upper)
работают, как ожидается, - перед выполнением операций целые преобразуются в плавающую форму.
Этот же пример сообщает чуть больше о том, как работает printf. функция printf фактически является универсальной функцией форматных преобразований, которая будет полностью описана в лекции № 7. Ее первым аргументом является строка символов, которая должна быть напечатана, причем каждый знак % указывает, куда должен подставляться каждый из остальных аргументов /второй, третий, .../ и в какой форме он должен печататься. Например, в операторе
printf("%4.0f %6.1f\n", fahr, celsius);
Спецификация преобразования %4.0f говорит, что число с плавающей точкой должно быть напечатано в поле шириной по крайней мере в четыре символа без цифр после десятичной точки. спецификация %6.1f описывает другое число, которое должно занимать по крайней мере шесть позиций с одной цифрой после десятичной точки, аналогично спецификациям f6.1 в фортране или f(6,1) в PL/1. Различные части спецификации могут быть опущены: спецификация %6f говорит, что число будет шириной по крайней мере в шесть символов; спецификация %2 требует двух позиций после десятичной точки, но ширина при этом не ограничивается; спецификация %f говорит только о том, что нужно напечатать число с плавающей точкой. функция printf также распознает следующие спецификации:
- %d - для десятичного целого,
- %о - для восьмеричного числа,
- %х - для шестнадцатеричного,
- %с - для символа,
- %s - для символьной строки
- %% - для самого символа %.