Арифметические операции

Операции

Язык C. Лекция 3

Как уже говорилось, определение типа данных состоит из двух частей — множества значений и набора операций. В предыдущей лекции мы рассмотрели множества значений для основных типов языка C. Осталось перечислить операции, которые можно выполнять над данными каждого типа.

Для данных типа int определены следующие арифметические операции:

+ — сложение,

- — вычитание,

* — умножение,

/ — деление нацело (дробная часть отбрасывается без округления, результат имеет тип int),

% — остаток от деления (если m и n — целые величины, то n*(m/n) + m%n = m).

Например, результат выражения 8/3 равен 2 (поскольку 8 и 3 являются константами типа int); выражение 8%3 также дает 2 (остаток от деления 8 на 3). Учтите, что деление выполняется таким способом лишь в том случае, если оба числа — делимое и делитель — имеют целый тип. Если хотя бы одно из чисел имеет тип float или double, то результат деления тоже будет иметь тип float или double (и будет вычислен с дробной частью; например, 8/3.0 даст результат 2.666666666666667, поскольку запись 3.0 по правилам языка C является константой типа double).

Перечисленные выше операции являются бинарными, или двуместными (т.е. они выполняются над двумя числами — операндами). Кроме того, есть еще унарные (одноместные) операции:

- — изменение знака числа на противоположный (например, -x)

+ — тождественная операция (введена для симметрии с унарным минусом).

Для чисел с плавающей точкой (типов float и double) определены первые четыре бинарные операции (т.е. сложение, вычитание, умножение и деление) и такие же унарные операции, как для типа int. Основное отличие от int заключается в выполнении деления: результат имеет тип float или double и может содержать дробную часть. Операция получения остатка от деления для типов с плавающей точкой не определена (отсутствует).

Тип char, как уже говорилось, соответствует коротким (8 двоичных разрядов) целым числам в диапазоне от 0 до 255 (без знака, unsigned char) либо от -128 до 127 (со знаком, signed char). Эти числа можно интерпретировать как коды (порядковые номера) алфавитных символов, а можно использовать и просто как числовые величины. Во всяком случае, над данными типа char можно выполнять те же арифметические операции, что и над типом int.

Арифметические операции (независимо от типа операндов) различаются по старшинству, или приоритету выполнения. В первую очередь выполняются операции, имеющие более высокий приоритет. Порядок выполнения операций с одинаковым приоритетом может быть любым (т.е. нельзя рассчитывать, что действия обязательно будут выполняться в том порядке, как они записаны). Например, в выражении a+b-c неизвестно, что будет выполнено раньше — сложение или вычитание.

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

Следует иметь в виду, что правила языка C разрешают компилятору выбрать любой порядок вычисления выражения, лишь бы при этом не нарушались законы математики. Например, нельзя сказать ничего определенного о том, в каком порядке будут складываться числа при вычислении выражения a + b + c: возможно, вначале будет получена сумма a + b, а затем к ней будет прибавлено число c. Может случиться и так, что вначале будет вычислено b + c, а потом к этой сумме прибавится a. С точки зрения математики оба варианта равноценны, а следовательно, компилятор вправе выбрать любой из них. Нельзя полагаться на то, что операции одного уровня старшинства в подобных выражениях обязательно будут выполнены в том порядке, как они написаны (слева направо).

Казалось бы, это правило о свободе выбора порядка вычислений не имеет большого значения, коль скоро гарантируется, что законы математики нарушены не будут. На самом деле это не совсем так. Порядок вычислений действительно не важен, если нет побочных эффектов. Однако, если отдельные части выражения сопряжены с побочными эффектами, то последовательность вычисления этих частей может влиять на конечный результат.