Операции, выражения и операторы

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

Бинарными (т. е. с двумя операндами) арифметическими операциями являются +, -, *, /, а также операция деления по модулю %. Деление целых сопровождается отбрасыванием дробной части, какой бы она ни была. Выражение x % y дает остаток от деления x на y и, следовательно, нуль, если x делится на y нацело. Операция % к операндам типов float и double не применяется. В какую сторону (в сторону увеличения или уменьшения числа) будет усечена дробная часть при выполнении / и каким будет знак результата операции % с отрицательными операндами, зависит от машины. Бинарные операции + и - имеют одинаковый приоритет, который ниже приоритета операторов *, / и %, который в свою очередь ниже приоритета унарных операторов + и -. Арифметические операции одного приоритетного уровня выполняются слева направо.

Если операнды операции принадлежат к разным типам, то они приводятся к некоторому общему типу. Приведение выполняется в соответствии с небольшим числом правил. Обычно автоматически производятся лишь те преобразования, которые без какой-либо потери информации превращают операнды с меньшим диапазоном значений в операнды с большим диапазоном, как, например, преобразование целого в число с плавающей точкой в выражении вроде f + i. Выражения, в которых могла бы теряться информация (скажем, при присваивании длинных целых переменным более коротких типов или при присваивании значений с плавающей точкой целым переменным), могут повлечь за собой предупреждение, но они допустимы. Значения типа char - это просто малые целые, и их можно свободно использовать в арифметических выражениях, что значительно облегчает всевозможные манипуляции с символами.

Операции и приоритеты

Приоритет арифметических операций естественный. Операции сравнения = =, != имеют приоритет более низкий, чем операции отношения. Операции отношения <, >, <=, >= имеют одинаковый приоритет, более низкий, чем приоритет арифметических операций. Из объектов, имеющих одинаковые или разные типы, составляют выражения, указывая операции, которые надо выполнить над объектами. Например, x – y = = c. По определению численным результатом вычисления выражения отношения (сравнения) является 1, если оно истинно, и 0, если ложно. Для явного указания порядка вычислений используют круглые скобки. Например, (a + b) / 2 / d.

Преобразования типов

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

Операции присваивания

Выражение <Lvalue> = <Rvalue> есть выражение присваивания. В левой части находится переменная, в правой части – ее значение. Значение может быть константой, переменной, значение которой определено, выражением. Например, x = 0, y = x, z = x + y.

Выражение присваивания i = i + 2, в котором стоящая слева переменная повторяется и справа, можно написать в сжатом виде: i += 2. Операция +=, как и =, называется операцией присваивания. Большинству бинарных операций (аналогичных + и имеющих левый и правый операнды) соответствуют операции присваивания op=, где op ‑ одна из операций + - * / % << >> & ^ |. Если i ‑ переменная и e ‑ выражение, то i op= e эквивалентно i = i op (e) с той разницей, что i вычисляется только один раз. Обратите внимание на скобки вокруг e: x *= y + 1 эквивалентно x = x * (y + 1), но не x = x*y+1. Помимо краткости, операции присваивания обладают тем преимуществом, что они более соответствуют тому, как человек мыслит. Мы говорим "прибавить 2 к i" или "увеличить i на 2", а не "взять i, добавить 2 и затем вернуть результат в i", так что выражение i += 2 лучше, чем i = i + 2. Следует иметь в виду и то, что подобные операции присваивания могут помочь компилятору сгенерировать более эффективный код. Типом и значением любого выражения присваивания являются тип и значение его левого операнда после завершения присваивания.

Инкремент ++и декремент --

Операция ++ явно задает инкремент в отличие от неявного его задания с помощью сложения и присваивания. Различают постфиксный инкремент lvalue ++ и префиксный инкремент ++ lvalue.

По определению ++lvalue означает lvalue+=1, что, в свою очередь означает lvalue=lvalue+1 при условии, что содержимое lvalue не вызывает побочных эффектов. Выражение, обозначающее операнд инкремента, вычисляется только один раз.

Операции ++ и - - могут использоваться как префиксные и постфиксные операции. Значением ++x является новое (т. е. увеличенное на 1) значение x. Например, y = ++x эквивалентно y = (x += 1). Напротив, значение x++ равно прежнему значению x. Например, y = x++ эквивалентно y = (t = x, x += 1, t), где t - переменная того же типа, что и x.

Аналогично определяется операция декремента (--). Различают постфиксный декремент lvalue – и префиксный декремент – lvalue. По определению --lvalue означает lvalue -= 1.

Выражение и оператор

Выражение, скажем x = 0, или i++, или printf(…), становится оператором, если в конце его поставить точку с запятой, например: x = 0; i++; printf(...); В Си точка с запятой является заключающим символом оператора, а не разделителем. Фигурные скобки { и } используются для объединения объявлений и операторов в составной оператор, или блок, чтобы с точки зрения синтаксиса эта новая конструкция воспринималась как один оператор. После правой закрывающей фигурной скобки в конце блока точка с запятой не ставится.

Упражнения

Найдите ошибки в программе

#include studio.h main { int i i := 43 print ('В году i недель') }

Что будет напечатано в приведенном примере, который является частью полной программы:

int n; n = 2; printf ("%d + %d = %d\n", n, n, n + n);

Что будет результатом каждого выражения:

a = b = 5 a + b a++ + b ++a + b --a + b a-- + b

Задачи для решения

1. Даны две целых переменных a и b. Обменять их значения.

2. Дано натуральное число в шестнадцатеричной системе счисления. Напечатайте его значение в десятичной системе счисления.

3. Дано два целых числа. Напечатайте сумму, разность и произведение данных чисел.

4. В прямоугольнике даны длины сторон. Вычислите и напечатайте периметр и площадь прямоугольника.

5. Дано два натуральных числа. Вычислите и напечатайте их частное и остаток от деления.

6. Дано натуральное двузначное число. Напечатайте сумму его цифр. Например, сумма цифр двузначного числа 92 равна одиннадцати.

7. Даны целые коэффициенты квадратного уравнения . Вычислите и напечатайте его дискриминант .

8. Целая переменная c должна использоваться как переключатель, т.е. если ее значение равно 0 (выключено), то ей следует присвоить значение 1 (включено), и наоборот. Напишите программу, которая преобразует введенное значение c. Условный оператор не использовать.

9. Цвета в шестнадцати цветовой палитре делятся на тёмные (с номерами от 0 до 7) и светлые (с номерами от 8 до 15) так, что каждому тёмному цвету соответствует светлый. Например, тёмному цвету 1 соответствует светлый цвет 9, а светлому цвету 14 соответствует тёмный цвет 6. По заданному номеру цвета вычислите номер соответствующего ему цвета.

10. Дана целая переменная a, не равная нулю. Присвойте ей противоположное значение и напечатайте его. Например, если значение переменной a равно -15, то противоположным значением будет 15.

11. Вычислите сумму первых n членов натурального ряда чисел.

12. Вычислите n-ый член арифметической прогрессии по заданному первому члену a и разности d.

13. Дано натуральное трехзначное число. Напечатайте сумму цифр этого числа.

14. До 1971 года в Англии в денежной системе использовались следующие единицы: 1 фунт стерлингов = 20 шиллингов; 1 шиллинг = 12 пенсов. “Нищий” в Сити в среднем зарабатывал P пенсов. Сколько это составляет фунтов, шиллингов и пенсов. Например, 512 пенсов составляют 42 шиллинга и 8 пенсов, а 42 шиллинга составляют 2 фунта и 2 шиллинга. Ответом будет 2, 2 и 8.

15. На 1 января приходится понедельник — первый день недели. От начала года идёт k-ый день. Какой это день недели (указать порядковый номер дня недели)?

Указания и решения

Обмен значениями с использованием третьей переменной Обмен значениями без использования третьей переменной. Используется в случае дефицита памяти.
int main(void) { int a, b; //здесь ввод входных данных int c = a; a = b; b = c; //здесь вывод результата return 0; } int main(void) { int a, b; //здесь ввод входных данных a = b - a; b = b - a; a = a + b; //здесь вывод результата return 0; }
  1. Используем функцию scanf() из <stdio.h>, позволяющую указать формат вводимых данных.

int a;

scanf("%x", &a);//вводится целое шестнадцатеричное число

Вводим с клавиатуры шестнадцатеричное число. Например, 1f.

  1. Без комментариев.
  2. Без комментариев.
  3. Без комментариев.
  4. В десятичной системе счисления двузначное число , где d - цифра десятков, а e - цифра единиц. Очевидно, что d = n /10, e = n % 10.
  5. b2 = b*b.
  6. с = 1 - с.
  7. с = (с + 8) % 16.
  8. c = -c.
  9. S = 1 + 2 + ... + n = (1 + n)*n / 2.
  10. Без комментариев.
  11. См. комментарий к задаче 6.
  12. Количество шиллингов - это частное от деления количества пенсов на 12. Количество фунтов - частное от деления количества шиллингов на 20.

int k; //день от начала года

int d; //день недели

//здесь ввод входных данных

d = (k-1) % 7 +1;

//здесь вывод результата

Справочная информация. Таблица приоритетов операций

Операции с одинаковым приоритетом выполняются слева направо в порядке следования.