Содержание
При изучении любого языка программирования, будь то Delphi, Python или C#, одной из основных тем изучения на начальном этапе является перечень основных операторов в языке и их применение. Конечно, со временем работать с теми или иными операторами начинаешь, как говориться, «на автомате», но в самом начале пути изучения нового языка эта тема является безусловно одной из основных. В этой части мы рассмотрим основные арифметические операторы и их действие в C#
Арифметические операторы C#
Арифметические операторы в C# делятся на две группы: унарные и бинарные.
Унарным называется оператор, который применяется к одному выражению. При этом, под выражением может пониматься отдельная переменная. К унарным арифметическим операторам в C# относят:
++
(приращение),--
(уменьшение),+
(плюс) и-
(минус)
к бинарным, то есть таким операторам, которые применяются к двум выражениям, относятся:
*
(умножение),/
(деление),%
(остаток от деления),+
(сложение) и-
(вычитание).
Рассмотрим работу этих операторов подробнее.
Унарные арифметические операторы C#
Операторы приращения (++) и уменьшения (—)
Оператор приращения (инкремента) ++
увеличивает операнд на 1, а оператор уменьшения (декремента) --
, соответственно, уменьшает операнд на 1.
Например, результатом выполнения вот такого кода:
int i = 1; i++; Console.WriteLine(i);
будет строка:
Операторы инкремента и декремента в C# поддерживается в двух формах: постфиксной (например, x++
) и префиксной (например, ++x
).
Результатом постфиксного оператора приращения или уменьшения является значение переменной перед выполнением операции, а результатом префиксного оператора, соответственно, значение переменно после выполнения операции. Чтобы понять суть работы префиксной и постфиксной формы рассмотрим следующий пример:
int a = 1; int b = a++; Console.WriteLine(b);
здесь мы используем постфиксную форму, то есть программа будет работать следующим образом:
- Переменной
a
присваивается значение1
- Переменной
b
присваивается значение переменнойa
, то есть 1 - Значение переменной
a
увеличивается на1
и становится равным2
Если нам необходимо, чтобы переменная b
получила значение 2
, то необходимо воспользоваться префиксной формой инкремента:
int a = 1; int b = ++a; Console.WriteLine("a = {0}", a); Console.WriteLine("b = {0}", b);
В итоге, в консоли мы увидим:
b = 2
Теперь попробуем ответить на такой вопрос: какое значение будет иметь переменная i
:
int i = 0; i = i++;
Ответ: i
— она останется равной нулю. Причина такого поведения C# описана выше — использовалась постфиксная форма инкремента (сначала мы присвоили переменной i
её же значение, то ест ноль и только после этого увеличили значение переменной на 1).
Унарные операторы плюса и минуса
Унарный оператор +
возвращает значение полученного операнда, то есть, по сути, ничего не делает. Унарный оператор -
изменяет знак операнда на противоположный. Здесь никаких «подводных камней» нет и результат выполнения следующего кода можно угадать с первого раза:
double f = -4.45; int i = 10; Console.WriteLine("+f = {0}, -i = {1}", +f, -i);
Результатом будет строка:
Остается только отметить, что целочисленный тип ulong
не поддерживает унарный минус. Если мы попытаемся сделать вот так:
ulong i = 10; Console.WriteLine("-i = {0}", -i);
То ещё до компиляции получим ошибку:
Бинарные арифметические операторы
Умножение (*)
Оператор умножения *
вычисляет произведение операндов, например:
ushort a = 10; //создали переменную int b = 5; //создали переменную b Console.WriteLine(a * b);
вернет значение 50
, а типом данных для произведения будет, int
. Соответственно, в этом примере:
float a = 10.0f; //создали переменную int b = 5; //создали переменную b Console.WriteLine((a * b).GetType()); Console.ReadLine();
Программа вернет нам вещественный тип float.
То есть при выполнении бинарных операторов платформа .NET пытается использовать для результата вычисления наиболее «вместительный» тип данных. В первом случае, при перемножении двух целых чисел, для результата вычисления был выбран тип int
, так как разрядность int
больше, чем у ushort
. Почему так происходит и зачем нам такое поведение мы поймем чуть позже. Немного по другому работает оператор деления.
Деление (/)
В C# различают деление целых чисел и деление чисел с плавающей точкой (запятой).
Для операндов целочисленных типов (int
, short
, uint
и т.д.) результат оператора /
является целочисленным типом, который равен частному двух операндов, округленному в сторону нуля. Например,
int a = 10; int b = 3; Console.WriteLine(a/b);
в консоли мы увидим
а не 3,3333
. Аналогичный результат мы получим, если будем использовать обычные целочисленные литералы:
Console.WriteLine(10/3);
Чтобы получить вещественный результат, один или оба операнда должны иметь вещественный тип. Например:
double a = 10.0; int b = 3; Console.WriteLine(a/b);
Так как в выражении a/b
один из операндов имеет вещественный тип, то в консоли мы увидим:
Для типов float
, double
и decimal
результатом оператора /
является частное двух операндов. Однако и здесь есть момент, который стоит помнить, а именно: если один из операндов — это decimal
, второй операнд не может быть ни float
, ни double
Остаток от деления (%)
Для целочисленных операндов результатом a % b
является значение полученное из выражения a - (a / b) * b
. Знак ненулевого остатка такой же, как и у левого операнда, например:
int a = 10; int b = 3; Console.WriteLine(a % b);
вернет нам значение 1. В C# можно получить остаток от деления вещественных чисел, например:
double a = 10.4; double b = 3.45; Console.WriteLine(a % b);
Вернет значение
Операторы сложения (+) и вычитания (-)
Эти операторы так же, как и везде производят математическое сложение/вычитание правого операнда из левого. Никаких подводных камней и особенностей в этом плане в C# нет.
int a = 10; double b = 3.45; Console.WriteLine(a - b);
вернет
Операторы составного присваивания
В C# имеются также операторы составного присваивания, которые можно использовать, для более короткой записи арифметических операций и в общем случае выглядят следующим образом:
x [op]= y
где [op]
— какой-либо из рассмотренных выше операторов. Читается такое выражение в развернутом виде следующим образом:
x = x [op] y
Например,
int a = 10; a += 10; //a=a+10 = 20; Console.WriteLine(a); a /= 10; //a = a/10 = 2; Console.WriteLine(a); a *= 5; //a = a*5 = 10 Console.WriteLine(a); a %= 3; //a = a % 3 = 1 Console.WriteLine(a);
вернет нам значения, которые написаны в комментариях к коду, то есть строки:
2
10
1
Приоритет и ассоциативность операторов
Арифметические операторы выполняются в следующем порядке (по убыванию приоритета):
- Постфиксный инкремент
x++
и декрементx--
- Префиксный инкремент
++x
и декремент--x
, унарные операторы+
и-
- Мультипликативные операторы
*
,/
, и%
- Аддитивные операторы
+
и-
Бинарные арифметические операторы имеют левую ассоциативность. То есть операторы с одинаковым приоритетом вычисляются в направлении слева направо. Порядок вычисления, определяемый приоритетом и ассоциативностью операторов, можно изменить с помощью скобок (()
).
Для удобства сведем все рассмотренные математические операторы C# в таблицу и расположим их в порядке убывания приоритета.
Таблица математических операторов C# в порядке убывания приоритета
В таблице значение приоритета 1 означает высший приоритет, а 4 — низший.
Приоритет | Группа операторов | Подгруппа | Название операторов | Запись в C# |
1 | Унарные операторы | Постфиксный инкремент | x++ |
|
1 | Постфиксный декремент | x-- |
||
2 | Префиксный инкремент | ++x |
||
2 | Префиксный декремент | --x |
||
2 | Унарный плюс | +x |
||
2 | Унарный минус | -x |
||
3 | Бинарные операторы | Мультипликативные операторы | Умножение | x * y |
3 | Деление | x / y |
||
3 | Остаток от деления | x % y |
||
4 | Аддитивные операторы | Сложение | x + y |
|
4 | Вычитание | x - y |
Головоломка для начинающих (и отдельный котёл в аду за такие операции для опытных). Чему будет равно выражение:
int a = 10; int b = 2; int c = 3; var d=-a++-b---c;
Код приведен только в качестве примера. Никогда так не делайте! Особенно, если работаете в команде — могут побить
Чтобы понять, что мы получим в итоге, первое, что необходимо сделать — это отформатировать код. Наличие пробелов между операторами позволит приблизится к решению задачи с сделает код чуточку понятнее:
var d = -a++ - b-- - c;
теперь смотрим на унарные операторы — их у нас два (a++
и b--
). Оба оператора — постфиксные, то есть на результат вычисления значения переменной d
они никак не повлияют. В итоге остается вот такое выражение:
var d = -10 - 2 - 3;
Ответ: -15.
Чтобы изменить приоритет выполнения арифметических операций, мы можем использовать тот же принцип, что и в математике, то есть использовать скобки.
Итого
Сегодня мы узнали, какие виды арифметических операторов есть в C#, как они работают и в чем их особенности. А также разобрали несколько примеров, показывающих особенности вычисления арифметических выражений в C#.