Арифметические операторы C#

При изучении любого языка программирования, будь то Delphi, Python или C#, одной из основных тем изучения на начальном этапе является перечень основных операторов в языке и их применение. Конечно, со временем работать с теми или иными операторами начинаешь, как говориться, «на автомате», но в самом начале пути изучения нового языка эта тема является безусловно одной из основных. В этой части мы рассмотрим основные арифметические операторы и их действие в C#

Арифметические операторы C#

Арифметические операторы в C# делятся на две группы: унарные и бинарные.

Унарным называется оператор, который применяется к одному выражению. При этом, под выражением может пониматься отдельная переменная. К унарным арифметическим операторам в C# относят:

  • ++ (приращение),
  • -- (уменьшение),
  • + (плюс) и - (минус)

к бинарным, то есть таким операторам, которые применяются к двум выражениям, относятся:

  • * (умножение),
  • / (деление),
  • % (остаток от деления),
  • + (сложение) и - (вычитание).

Рассмотрим работу этих операторов подробнее.

Унарные арифметические операторы C#

Операторы приращения (++) и уменьшения (—)

Оператор приращения (инкремента) ++ увеличивает операнд на 1, а оператор уменьшения (декремента) --, соответственно, уменьшает операнд на 1.

Например, результатом выполнения вот такого кода:

int i = 1;
i++;
Console.WriteLine(i);

будет строка:

2

Операторы инкремента и декремента в C# поддерживается в двух формах: постфиксной (например, x++) и префиксной (например, ++x).

Результатом постфиксного оператора приращения или уменьшения является значение переменной перед выполнением операции, а результатом префиксного оператора, соответственно, значение переменно после выполнения операции. Чтобы понять суть работы префиксной и постфиксной формы рассмотрим следующий пример:

int a = 1;
int b = a++;
Console.WriteLine(b);

здесь мы используем постфиксную форму, то есть программа будет работать следующим образом:

  1. Переменной a присваивается значение 1
  2. Переменной b присваивается значение переменной a, то есть 1
  3. Значение переменной a увеличивается на 1 и становится равным 2

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

int a = 1;
int b = ++a;
Console.WriteLine("a = {0}", a);
Console.WriteLine("b = {0}", b);

В итоге, в консоли мы увидим:

a = 2
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);

Результатом будет строка:

+f = -4,45, -i = -10

Остается только отметить, что целочисленный тип ulong не поддерживает унарный минус. Если мы попытаемся сделать вот так:

ulong i = 10;
Console.WriteLine("-i = {0}", -i);

То ещё до компиляции получим ошибку:

Ошибка CS0023 Оператор «-» невозможно применить к операнду типа «ulong»

Бинарные арифметические операторы

Умножение (*)

Оператор умножения * вычисляет произведение операндов, например:

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

а не 3,3333. Аналогичный результат мы получим, если будем использовать обычные целочисленные литералы:

Console.WriteLine(10/3);

Чтобы получить вещественный результат, один или оба операнда должны иметь вещественный тип. Например:

double a = 10.0;
int b = 3;
Console.WriteLine(a/b);

Так как в выражении a/b один из операндов имеет вещественный тип, то в консоли мы увидим:

3,3333333333333335

Для типов 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);

Вернет значение

0,0499999999999998

Операторы сложения (+) и вычитания (-)

Эти операторы так же, как и везде производят математическое сложение/вычитание правого операнда из левого. Никаких подводных камней и особенностей в этом плане в C# нет.

int a = 10;
double b = 3.45;
Console.WriteLine(a - b);

вернет

6,55

Операторы составного присваивания

В 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);

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

20

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#.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии