+--------------------------+
|.------------------------.|
|| kee_reel@blog:~$ cd    ||
|| си python терминал     ||
|| opengl sql             ||
||                        ||
||                обо_мне ||
|.------------------------.|
+-::--------------------::-+
.--------------------------.
 // /ooooooooooooooooooooo\\ \\ 
 // /ooooooooooooooooooooooo\\ \\ 
//------------------------------\\
\\------------------------------//

C. Операторы

Оператор – это штука, с помощью которой можно совершить операцию (сложение, вычитание и т.д.)

Существует два вида операторов:

  • Унарные – для операций над одной переменной
  • Бинарные – для операций над двумя переменными

Есть ещё тернарный (с тремя переменными), но про него мы вспомним, когда будем говорить про условия (if, else).

Бинарные операторы

Начнём с бинарных, потому что они роднее и понятнее:

  • Сложение: +
  • Вычитание: -
  • Умножение: *
  • Деление: /
  • Остаток от деления: %

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

2 + 2 * 2 = ?

Если твой ответ 8, то ты забыл что умножение выполняется перед сложением. Здесь всё точно так же – сначала слева направо выполняются * / %, а затем так же выполняются + -.

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

(2 + 2) * 2 = 8

Операторы можно использовать разными способами:

  • С целочисленными значениями
  • С вещественными значениями
  • Со смешанными значениями
  • С приведением типа
  • С операцией присваивания
  • Для злодеев

Да, в языке C многовато тонкостей с операторами, но это всё само запомнится со временем – просто попробуй уловить основные моменты.

С целочисленными значениями

Вот примеры использования операций с целочисленными значениями:

int a = 15, b = 8;
int result;
result = a + b; // Присвоится 23
result = a - b; // Присвоится 7
result = a * b; // Присвоится 120
result = a / b; // Присвоится 1 потому что получается 1.875, а так как это целое число (int) -- дробная часть просто отбросится
result = a % b; // Присвоится 7 потому что при делении 15 на 8 получается 1 целая часть, и 7 в остатке
result = a + b * 2; // Присвоится 31
result = (a + b) * 2; // Присвоится 46

С вещественными значениями

Вот примеры использования операций с вещественными значениями:

float a = 7., b = 4.4;
float result;
result = a + b; // Присвоится 11.4
result = a - b; // Присвоится 2.6
result = a * b; // Присвоится 30.800001
// Почему 30.800001, а не 30.8? Потому что вычисления с float обладают точностью до определённого
// знака -- дальше этого знака может начаться безумие. Так происходит из-за особенности хранения
// вещественных чисел в памяти. Если использовать double вместо float, то точность повысится и
// возрастёт до более дальнего знака после запятой.
result = a / b; // Присвоится 1.590909
result = a % b; // !!! ОШИБКА, операция "%" не может использоваться с вещественными числами !!!

Обрати внимание, что оператор % не может использоваться с вещественнымим числами.

Со смешанными значениями

Окей, операции отдельно с целыми, отдельно с вещественными значениями понятны – а что если смешивать целые и вещественные в одной операции?

В этом случае, результат будет превращаться в вещественный:

int a = 5;
float b = 4.5;
float floatResult = a + b; // Присвоится 9.5
// Присвоится 9 потому что результат 9.5 засовывается в
// целочисленную переменную, и дробная часть отбрасывается
int intResult = a + b;
// Это справедливо и для всех остальных операций: - * /

С приведением типа

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

int a, b;
float result;
scanf("%d", &a); // Ввёл 6
scanf("%d", &b); // Ввёл 4
// Целочисленный результат 1 запишется в вещественную переменную,
// из-за чего целочисленное значение неявно приведётся к вещественное 1.000000
result = a / b;
print("%f\n", result); // Выведет 1.000000

Обрати внимание, что с этом случае мы записали целочисленное значение в вещественную переменную. В этом случае целочисленное значение неявно приводится к вещественному.

Что я могу сделать, чтобы получился правильный результат деления 1.5?

Для этого существует операция явного приведения типа – с её помощью можно прямо в выражении изменить тип значения переменной. Вот как это выглядит:

int a, b;
float result;
scanf("%d", &a);
scanf("%d", &b);
// Можно приводить к типу не только делимое, но и вообще любую переменную или число в выражении,
// и не только к double, но вообще к любому типу.
result = (double) a / b;
print("%f\n", result);

В этом случае выведется 1.500000, так как одна из переменных становится вещественной, а как мы знаем из предыдущего раздела “Со смешанными значениями” – “результат будет превращаться в вещественный”.

Я показал самый полезный случай использования приведения типа, но могут быть и какие-то другие экзотические случаи.

С операцией присваивания

Бинарные операторы можно красиво объединять с операцией присваивания:

int a = 3;
// Вот эта запись:
a = a + 10;
// Равноценна такой:
a += 10;
// Это справедливо для всех остальных операций: -= *= /= %=

Для злодеев

Просто чтоб ты знал – существует вариант использования присваивания с операторами для злодеев, который не надо использовать (но так можно):

int a = 2, b = 3, c = 4, d = 5;
a += (b += 5) * (c = 10) + d;
// Перепишу то же самое, но не по-злодейски:
b = b + 5; // Сначала выполняем первую скобку
c = 10; // Потом вторую
a = a + b * c + d; // Потом подставляем переменные в исходное выражение

Задание на закрепление

Я пока что дам пару простеньких заданий чтобы размять пальцы. Выдумывать какие-то сложные уравнения я не буду – просто если у тебя в будущем возникнет необходимость посчитать что-то сложное, то ты просто вернись к этом материалу. Через пару-тройку раз оно само засядет в подкорке.

Задания:

  • Напиши программу, которая принимает с клавиатуры (scanf) номер студента, и выводит (printf) номер его варианта. Всего вариантов от 1 до 15. Подсказка: %
  • Напиши программу, которая принимает с клавиатуры три вещественных числа, и выводит сумму двух первых чисел, умноженную на третье.

Унарные операторы

Раньше вы их скорее не встречали, так как они используются только в программированнии:

  • Инкремент (увеличивает значение переменной на 1): ++
  • Декремент (уменьшает значение переменной на 1): –

Вот так они используются:

int x = 5;
x++; // После этого x станет равен 6
x--; // А теперь x снова равен 5

С этими операторами есть хитрый момент – тут важно с какой стороны стоит оператор. Если оператор стоит:

  • Слева – операция происходит до получения значения переменной
  • Справа – операция происходит после получения значения переменной

Проще показать на примере:

int x, result;

x = 3;
// После этой строчки result станет равен 3, а x равен 4:
// то есть мы сначала выполнили операцию присваивания, а потом сделали инкремент переменной x
result = x++;

// Сбраcываем значение x на 3
x = 3;
// После этой строчки result равен 4, а равен 4:
// то есть мы сначала сделали инкремент, а потом выполнили операцию присваивания
result = ++x;

// Сбраcываем значение x на 3
x = 3;
// После этой строчки result равен 8, а x равен 4:
// то есть мы сначала выполнили операцию сложения, а потом сделали инкремент
result = x++ + 5;

// Сбраcываем значение x на 3
x = 3;
// После этой строчки result равен 9, а x равен 4:
// то есть мы сначала сделали инкремент, а потом выполнили операцию присваивания
result = ++x + 5;

Заключение

Итого, ты изучил:

  • Бинарные операторы
    • С целочисленными значениями
    • С вещественными значениями
    • Со смешанными значениями
    • С приведением типа
    • С операцией присваивания
    • Для злодеев
  • Унарные операторы

Если что – пиши, я помогу и постараюсь объяснить лучше.

Дальше на очереди – условия.