Язык С

       

Переменные и арифметика


Следующая программа печатает приведенную ниже таблицу температур по Фаренгейту и их эквивалентов по стоградусной шкале Цельсия, используя для перевода формулу

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 , TAK и 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" допускается совершенно произвольное расположение опера- торов в строке, подходящий сдвиг и использование пробелов значительно облегчают чтение программ. Мы рекомендуем писать только один оператор на строке и (обычно) оставлять пробелы вокруг операторов. Расположение фигурных скобок менее сущес- твенно; мы выбрали один из нескольких популярных стилей. Вы- берите подходящий для вас стиль и затем используйте его пос- ледовательно. Основная часть работы выполняется в теле цикла. Темпера- тура по Цельсию вычисляется и присваивается переменной CELAIUS оператором

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 - для символьной строки и %% - для самого символа %. Каждая конструкция с символом % в первом аргументе функ- ции PRINTF сочетается с соответствующим вторым, третьим, и т.д. Аргументами; они должны согласовываться по числу и ти- пу; в противном случае вы получите бессмысленные результаты. Между прочим, функция PRINTF не является частью языка "C"; в самом языке "C" не определены операции ввода-вывода. Нет ничего таинственного и в функции PRINTF ; это - просто полезная функция, являющаяся частью стандартной библиотеки подпрограмм, которая обычно доступна "C"-программам. Чтобы сосредоточиться на самом языке, мы не будем подробно оста- навливаться на операциях ввода-вывода до главы 7. В частнос- ти, мы до тех пор отложим форматный ввод. Если вам надо ввести числа - прочитайте описание функции SCANF в главе 7, раздел 7.4. Функция SCANF во многом сходна с PRINTF , но она считывает входные данные, а не печатает выходные.

Упражнение 1-3

---------------- Преобразуйте программу перевода температур таким обра- зом, чтобы она печатала заголовок к таблице.

Упражнение 1-4

---------------- Напишите программы печати соответствующей таблицы пере- хода от градусов цельсия к градусам фаренгейта.




    Содержание раздела