В C# используется большинство операций, которые применяются и в других языках программирования. Операции представляют определенные действия над операндами - участниками операции. В качестве операнда может выступать переменной или какое-либо значение (например, число). Операции бывают унарными (выполняются над одним операндом), бинарными - над двумя операндами и тернарными - выполняются над тремя операндами. Рассмотрим все виды операций.
Бинарные арифметические операции:
· +
Операция сложения двух чисел:
1 2 | int x = 10; int z = x + 12; // 22 |
· -
Операция вычитания двух чисел:
1 2 | int x = 10; int z = x - 6; // 4 |
· *
Операция умножения двух чисел:
1 2 | int x = 10; int z = x * 5; // 50 |
· /
Операция деления двух чисел:
1 2 3 4 5 6 | int x = 10; int z = x / 5; // 2 double a = 10; double b = 3; double c = a / b; // 3.33333333 |
При делении стоит учитывать, что если оба операнда представляют целые числа, то результат также будет округляться до целого числа:
1 | double z = 10 / 4; //результат равен 2 |
Несмотря на то, что результат операции в итоге помещается в переменную типа double, которая позволяет сохранить дробную часть, но в самой опеации участвуют два литерала, которые по умолчанию рассматриваются как объекты int, то есть целые числа, и результат то же будет целочисленный.
Для выхода из этой ситуации необходимо определять литералы или переменные, участвующие в операции, именно как типы double или float:
1 | double z = 10.0 / 4.0; //результат равен 2.5 |
· %
Операция получение остатка от целочисленного деления двух чисел:
1 2 | double x = 10.0; double z = x % 4.0; //результат равен 2 |
Также есть ряд унарных операций, в которых принимает участие один операнд:
· ++
Операция инкремента
Инкремент бывает префиксным: ++x - сначала значение переменной x увеличивается на 1, а потом ее значение возвращается в качестве результата операции.
И также существует постфиксный инкремент: x++ - сначала значение переменной x возвращается в качестве результата операции, а затем к нему прибавляется 1.
1 2 3 4 5 6 7 | int x1 = 5; int z1 = ++x1; // z1=6; x1=6 Console.WriteLine($"{x1} - {z1}"); int x2 = 5; int z2 = x2++; // z2=5; x2=6 Console.WriteLine($"{x2} - {z2}"); |
· --
Операция декремента или уменьшения значения на единицу. Также существует префиксная форма декремента (--x) и постфиксная (x--).
1 2 3 4 5 6 7 | int x1 = 5; int z1 = --x1; // z1=4; x1=4 Console.WriteLine($"{x1} - {z1}"); int x2 = 5; int z2 = x2--; // z2=5; x2=4 Console.WriteLine($"{x2} - {z2}"); |
При выполнении сразу нескольких арифметических операций следует учитывать порядок их выполнения. Приоритет операций от наивысшего к низшему:
1. Инкремент, декремент
2. Умножение, деление, получение остатка
3. Сложение, вычитание
Для изменения порядка следования операций применяются скобки.
Рассмотрим набор операций:
1 2 3 4 5 | int a = 3; int b = 5; int c = 40; int d = c---b*a; // a=3 b=5 c=39 d=25 Console.WriteLine($"a={a} b={b} c={c} d={d}"); |
Здесь мы имеем дело с тремя операциями: декремент, вычитание и умножение. Сначала выполняется декремент переменной c, затем умножение b*a, и в конце вычитание. То есть фактически набор операций выглядел так:
1 | int d = (c--)-(b*a); |
Но с помощью скобок мы могли бы изменить порядок операций, например, следующим образом:
1 2 3 4 5 | int a = 3; int b = 5; int c = 40; int d = (c-(--b))*a; // a=3 b=4 c=40 d=108 Console.WriteLine($"a={a} b={b} c={c} d={d}"); |
Лекция 3. Поразрядные операции
Особый класс операций представляют поразрядные операции. Они выполняются над отдельными разрядами числа. В этом плане числа рассматриваются в двоичном представлении, например, 2 в двоичном представлении 10 и имеет два разряда, число 7 - 111 и имеет три разряда.
Логические операции
· & (логическое умножение)
Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:
1 2 3 4 5 6 7 | int x1 = 2; //010 int y1 = 5;//101 Console.WriteLine(x1&y1); // выведет 0 int x2 = 4; //100 int y2 = 5; //101 Console.WriteLine(x2 & y2); // выведет 4 |
В первом случае у нас два числа 2 и 5. 2 в двоичном виде представляет число 010, а 5 - 101. Поразрядно умножим числа (0*1, 1*0, 0*1) и в итоге получим 000.
Во втором случае у нас вместо двойки число 4, у которого в первом разряде 1, так же как и у числа 5, поэтому в итоге получим (1*1, 0*0, 0 *1) = 100, то есть число 4 в десятичном формате.
· | (логическое сложение)
Похоже на логическое умножение, операция также производится по двоичным разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном разряде имеется единица. Например:
1 2 3 4 5 6 | int x1 = 2; //010 int y1 = 5;//101 Console.WriteLine(x1|y1); // выведет 7 - 111 int x2 = 4; //100 int y2 = 5;//101 Console.WriteLine(x2 | y2); // выведет 5 - 101 |
· ^ (логическое исключающее ИЛИ)
Также эту операцию называют XOR, нередко ее применяют для простого шифрования:
1 2 3 4 5 6 7 | int x = 45; // Значение, которое надо зашифровать - в двоичной форме 101101 int key = 102; //Пусть это будет ключ - в двоичной форме 1100110 int encrypt = x ^ key; //Результатом будет число 1001011 или 75 Console.WriteLine("Зашифрованное число: " +encrypt); int decrypt = encrypt ^ key; // Результатом будет исходное число 45 Console.WriteLine("Расшифрованное число: " + decrypt); |
Здесь опять же производятся поразрядные операции. Если у нас значения текущего разряда у обоих чисел разные, то возвращается 1, иначе возвращается 0. Таким образом, мы получаем из 9^5 в качестве результата число 12. И чтобы расшифровать число, мы применяем ту же операцию к результату.
· ~ (логическое отрицание или инверсия)
Еще одна поразрядная операция, которая инвертирует все разряды: если значение разряда равно 1, то оно становится равным нулю, и наоборот.
1 2 | int x = 9; Console.WriteLine(~x); |
Операции сдвига
Операции сдвига также производятся над разрядами чисел. Сдвиг может происходить вправо и влево.
· x<<y - сдвигает число x влево на y разрядов. Например, 4<<1 сдвигает число 4 (которое в двоичном представлении 100) на один разряд влево, то есть в итоге получается 1000 или число 8 в десятичном представлении.
· x>>y - сдвигает число x вправо на y разрядов. Например, 16>>1 сдвигает число 16 (которое в двоичном представлении 10000) на один разряд вправо, то есть в итоге получается 1000 или число 8 в десятичном представлении.
Таким образом, если исходное число, которое надо сдвинуть в ту или другую строну, делится на два, то фактически получается умножение или деление на два. Поэтому подобную операцию можно использовать вместо непосредственного умножения или деления на два.