Читать интересную книгу Язык Си - руководство для начинающих - M. УЭИТ

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 17 18 19 20 21 22 23 24 25 ... 98

butter = 25.0 + 60.0 * n / SCALE;

порядок операций следующий:

60.0 * n - первое умножение (или, возможно, деление) (если n = 6, то 60.0 * n = 360.0).

360.0/SCALE - второе умножение (или, возможно, деление) и наконец (поскольку SCALE = 2.0):

25.0 + 180.0 - первое сложение (или, возможно, вычитание) дает 205.0.

     Многие программисты предпочитают представлять порядок вычислений с помощью диаграммы специального вида, называемой "правом выражения". Ниже приводится пример такой диаграммы. Диаграмма показывает, как исходное выражение сводится к одному значению.

     Если вы захотите, скажем, чтобы сложение выполнялось перед делением, тогда вы должны делать то же, что и мы в приведенной ниже строке:

hour = (25.0 + 60.0 * n) / SCALE;

В первую очередь выполняется все, что заключено в скобки; внутри действуют обычные правила. В данном примере сначала вы умножение, а затем сложение. С помощью этих действий вычисляется выражение в скобках, и только потом результат делится на значение константы SCALE.

  

          Рис. 5.3. Деревья выражений, построенные на основе операции и операндов, и порядок вычислении.

     Мы можем составить таблицу правил, касающихся уже использованных нами операции. (В приложении В в конце книги приведена таблица, где содержатся правила, относящиеся ко всем операциям языка Си.)

Таблица 5.1. Операции в порядке уменьшения уровня старшинства

ОПЕРАЦИИ ПОРЯДОК ВЫЧИСЛЕНИЯ ( ) слева направо -(унарный) слева направо * / слева направо + -(вычитание) слева направо = слева направо

     Заметим, что два различных по смыслу употребления знака минус имеют разные приоритеты (уровни старшинства). Столбец "порядок вычисления" указывает, как операция связана со своими операндами. Например, унарный знак минус связан с величиной, стоящей справа от него, а при делении левый операнд делится на правый.

Попытаемся применить эти правила на более сложном примере

/* применение правил старшинства */

main( )

{

 int top, score;

top = score = -(2 + 5)*6 + (4 + 3*(2 + 3));

printi("top = %d n", top);

}

     Какое значение будет выведено на печать в результате работы данной программы? Вначале вычислите его сами, а затем выполните программу или прочитайте нижеследующее объяснение, чтобы проверить свой ответ. (Надеемся, что вы получите правильный результат.)

     Итак, выражения, стоящие в скобках, имеют наивысший приоритет. Двигаясь слева направо, встречаем первое выражение скобках (2+5). Вычисляя его, получаем:

top = score = -7*6 + (4 + 3*(2 + 3))

     Следущее выражение в скобках - это (4 + 3*(2 + 3)). Отбрасываем скобки, получаем 4 + 3*(2 + 3). Вот как! Еще одни скобки! Тогда первым шагом является нахождение суммы 2+3. Выражение примет вид:

top = score = -7*6 + (4 + 3*5)

     Мы должны еще завершить вычисление выражения в скобках. По-скольку умножение * имеет приоритет более высокий, чем сложение, выражение теперь выглядит так

top = score = -7*6 + (4 + 15)

имеем

top = score = -7*6 + 19.

     Что же дальше? Если вы предполагаете, что нужно найти произведение 7*6, то вы ошибаетесь. Заметим, что унарный минус (изменение знака) имеет более высокий приоритет, чем умножение *. Поэтому сначала число 7 заменяется на -7, а затем -7 умножается на 6. Строка примет вид:

top = score = -42 + 19

после этого в результате сложения получим

toр  = score = -23

     Затем переменной score присваивается значение -23, и, наконец, переменная top получает то же значение -23. Напомним, что операция = выполняется справа налево.

НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ОПЕРАЦИИ

     В языке Си имеется около 40 операций, но некоторые из них используются гораздо чаще, чем другие. Те операции, которые мы толькo что рассмотрели, являются наиболее общеупотребительными. Кроме того, нам хотелось бы привести еще три полезные операции.

Операция деления по модулю: %

     Операция деления по модулю используется в целочисленной арифметикe. Ее результатом является остаток от деления целого числа, стоящего слева от знака операции, на число, расположенное справa от него. Например, 13 % 5 (читается как "13 по модулю 5") имеет значение 3, поскольку справедливо равенство 13 = 2*5 + 3.

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

     На первый взгляд эта операция может показаться некоторым экзотическим средством, используемым лишь математиками, но на самом деле она применяется на практике и довольно удобна при программировании ряда задач. Одно широко распространенное применение - содействие пользователю в управлении ходом программы. Предположим, например, что вы пишите программу обработки счетов, которая должна предусматривать дополнительную плату раз в три месяца. Для этого нужно только вычислить оста ток от деления номера месяца на 3 (т.е. month % 3), проверить, равен ли результат 0, и, если равен, добавить к счету величину дополнительной платы. После того как вы познакомились с "оператором if", вы сможете лучше представить себе, как все это работает.

Приведем пример программы, использующей операцию %

/* секунды в минуты */

/* переводит секунды в минуты и секунды */

 #define SM 60 /* число секунд в минуте */

main( )

{

int sec, mm, left;

printf(" Перевод секунд в минуты и секунды ! n");

printf(" Укажите число секунд, которое вы хотели бы перевести в минуты n" );

scanf(" %d", &sec); /* ввод числа секунд */

mm = sec %  SM; /* число минут */

left = sec % SM; /* оставшееся число секунд */

printf(" %d секунды это %d минуты, %d секунды n", sec, mm, left);

}

Вот результат ее работы

Перевод секунд в минуты и секунды!

Укажите число секунд, которое вы хотели бы перевести в минуты.

234

234 секунды это 3 минуты 54 секунды.

     Недостатком этой диалоговой программы является то, что она обрабатывает только одну входную величину. Сумеете ли вы сами изменить программу так, чтобы она предлагала вам вводить новые значения? Мы вернемся к этой задаче в разделе вопросов в конце главы, но, если вы найдете свое собственное решение, мы будем очень рады.

Операции увеличения и уменьшения: ++ и --

     Операция увеличения осуществляет следующее простое действие: она увеличивает значение своего операнда на единицу. Существуют две возможности использования данной операции, первая:

     когда символы ++ находятся слева от переменной (операнда), - "префиксная" форма,

и вторая:

     когда символы ++ стоят справа от переменной, - "постфиксная" форма.

Эти две формы указанной операции различаются между собой только тем, в какой момент осуществляется увеличение операнда. Сначала мы обсудим сходство указанных двух форм, а затем вернемся к различиям. Короткий пример, приведенный ниже, показывает, как выполняется данная операция.

/*выполнение сложения */

main( ) /*увеличение префиксная и постфиксная формы */

{

int ultra = 0, super = 0;

 while (super < 6)

 {

     super++;

    ++ultra;

    printf(" super = %d, ultra = %dn", super, ultra);

}

}

Результаты работы программы "выполнение сложения" выглядят слeдyющим образом

super = 1, ultra = 1

super = 2, ultra = 2

super = 3, ultra = 3

super = 4, ultra = 4

super = 5, ultra = 5

     Вот это да! Мы досчитали до 5! Дважды! Одновременно! (Если вы захотите считать дальше, вам необходимо будет только изменить параметр, определяющий верхний предел счета в операторе while).

 

     Признаемся, что мы могли бы получить тот же результат, заменив два оператора увеличения следующими операторами присваивания

super = super + 1, ultra = ultra + 1,

     Данные операторы выглядят достаточно простыми. В связи с этим возникает вопрос, зачем нужен еще один дополнительный оператор, не говоря уже о двух, да еще в сокращенной форме?

1 ... 17 18 19 20 21 22 23 24 25 ... 98
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Язык Си - руководство для начинающих - M. УЭИТ.

Оставить комментарий