Как видите, приведение результата, возвращаемого методом Math.Sqrt(), к типу int позволяет получить целую часть числа. Так, в выражении Math.Sqrt(n) - (int) Math.Sqrt(n)
приведение к типу int дает целую часть числа, которая затем вычитается из всего числа, а в итоге получается дробная его часть. Следовательно, результат вычисления данного выражения имеет тип double. Но к типу int приводится только значение, возвращаемое вторым методом Math.Sqrt().
ГЛАВА 4. Операторы
В языке C# предусмотрен обширный ряд операторов, предоставляющих программирующему возможность полного контроля над построением и вычислением выражений. Большинство операторов в С# относится к сле дующим категориям: арифметические, поразрядные, логиче ские и операторы отношения. Все перечисленные категории операторов рассматриваются в этой главе. Кроме того, в C# предусмотрен ряд других операторов для особых случаев, включая индексирование массивов, доступ к членам класса и обработку лямбда-выражений. Эти специальные опера торы рассматриваются далее в книге вместе с теми сред ствами, в которых они применяются. Арифметические операторы
Арифметические операторы, представленные в языке С#, приведены ниже. Оператор Действие + Сложение - Вычитание, унарный минус * Умножение / Деление % Деление по модулю — Декремент ++ Инкремент
Операторы +, -, * и / действуют так, как предполагает их обозначение. Их можно применять к любому встроенному числовому типу данных.
Действие арифметических операторов не требует особых пояснений, за исключени ем следующих особых случаев. Прежде всего, не следует забывать, что когда оператор / применяется к целому числу, то любой остаток от деления отбрасывается; например, результат целочисленного деления 10/3 будет равен 3. Остаток от этого деления можно получить с помощью оператора деления по модулю (%), который иначе называется оператором вычисления остатка. Он дает остаток от целочисленного деления. Напри мер, 10 % 3 равно 1. В C# оператор % можно применять как к целочисленным типам данных, так и к типам с плавающей точкой. Поэтому 10.0 % 3.0 также равно 1. В этом отношении C# отличается от языков С и C++, где операции деления по модулю разрешаются только для целочисленных типов данных. В приведенном ниже примере программы демонстрируется применение оператора деления по модулю. // Продемонстрировать применение оператора %. using System; class ModDemo { static void Main() { int iresult, irem; double dresult, drem; iresult = 10 / 3; irem = 10 % 3; dresult = 10.0 / 3.0; drem = 10.0 % 3.0; Console.WriteLine("Результат и остаток от деления 10/3: " + iresult + " " + irem); Console.WriteLine("Результат и остаток от деления 10.0 / 3.0: " + dresult + " " + drem); } }
Результат выполнения этой программы приведен ниже. Результат и остаток от деления 10 / 3: 3 1 Результат и остаток от деления 10.0 / 3.0: 3.33333333333333 1
Как видите, обе операции, % целочисленного типа и с плавающей точкой, дают один и тот же остаток, равный 1. Операторы инкремента и декремента
Операторы инкремента (++) и декремента (--) были представлены в главе 2. Как станет ясно в дальнейшем, они обладают рядом особых и довольно интересных свойств. Но сначала выясним основное назначение этих операторов.
Оператор инкремента увеличивает свой операнд на 1, а оператор декремента уменьшает операнд на 1. Следовательно, оператор х++;
равнозначен оператору х = x + 1;
а оператор х--;
равносилен оператору х = х - 1;
Следует, однако, иметь в виду, что в инкрементной или декрементной форме зна чение переменной х вычисляется только один, а не два раза. В некоторых случаях это позволяет повысить эффективность выполнения программы.
Оба оператора инкремента и декремента можно указывать до операнда (в префикс ной форме) или же после операнда (в постфиксной форме). Например, оператор х = х + 1;
может быть записан в следующем виде: ++х; // префиксная форма
или же в таком виде: х++; // постфиксная форма
В приведенном выше примере форма инкремента (префиксная или постфиксная) особого значения не имеет. Но если оператор инкремента или декремента использу ется в длинном выражении, то отличие в форме его записи уже имеет значение. Когда оператор инкремента или декремента предшествует своему операнду, то результатом операции становится значение операнда после инкремента или декремента. А когда оператор инкремента или декремента следует после своего операнда, то результатом операции становится значение операнда до инкремента или декремента. Рассмотрим следующий фрагмент кода. х = 10; у = ++х;
В данном случае значение переменной у будет установлено равным 11, поскольку значение переменной х сначала увеличивается на 1, а затем присваивается переменной у. Но во фрагменте кода х = 10; у = х++;
значение переменной у будет установлено равным 10, так как в этом случае значение переменной х сначала присваивается переменной у, а затем увеличивается на 1. В обо их случаях значение переменной х оказывается равным 11. Отличие состоит лишь том, когда именно это значение станет равным 11: до или после его присваивания пере менной у.
Возможность управлять моментом инкремента или декремента дает немало пре имуществ при программировании. Обратимся к следующему примеру программы, в которой формируется последовательный ряд чисел. // Продемонстрировать отличие между префиксной // и постфиксной формами оператора инкремента (++). using System; class PrePostDemo { static void Main() { int x, y; int i; x = 1; У = 0; Console.WriteLine("Ряд чисел, полученных " + "с помощью оператора у = у + х++;"); for(i = 0; i < 10; i++) { у = у + х++; // постфиксная форма оператора ++ Console.WriteLine(у + " "); } Console.WriteLine(); x = 1; У = 0; Console.WriteLine("Ряд чисел, полученных " + "с помощью оператора у = у + ++х;"); for(i = 0; i < 10; i++) { у = у + ++х; // префиксная форма оператора ++ Console.WriteLine(у + " "); } Console.WriteLine(); } }
Выполнение этой программы дает следующий результат. Ряд чисел, полученных с помощью оператора у = у + х++ 1 3 6 10 15 14 21 28 36 45 55 Ряд чисел, полученных с помощью оператора у = у + ++х; 2 5 9 14 20 27 35 44 54 65
Как подтверждает приведенный выше результат, в операторе у = у + х++;
первоначальное значение переменной х складывается с самим собой, а полученный результат присваивается переменной у. После этого значение переменной х увеличи вается на 1. Но в операторе у = у + ++х;
значение переменной х сначала увеличивается на 1, затем складывается с первоначаль ным значением этой же переменной, а полученный результат присваивается пере менной у. Как следует из приведенного выше результата, простая замена префиксной формы записи оператора ++х постфиксной формой х++ приводит к существенному изменению последовательного ряда получаемых чисел.
И еще одно замечание по поводу приведенного выше примера: не пугайтесь выра жений, подобных следующему: у + ++x
Такое расположение рядом двух операторов может показаться не совсем привыч ным, но компилятор воспримет их в правильной последовательности. Нужно лишь запомнить, что в данном выражении значение переменной у складывается с увеличен ным на 1 значением переменной х. Операторы отношения и логические операторы
В обозначениях оператор отношения и логический оператор термин отношения озна чает взаимосвязь, которая может существовать между двумя значениями, а термин логический — взаимосвязь между логическими значениями "истина" и "ложь". И по скольку операторы отношения дают истинные иди ложные результаты, то они неред ко применяются вместе с логическими операторами. Именно по этой причине они и рассматриваются совместно в данном разделе.
Ниже перечислены операторы отношения. Оператор Значение == Равно != Не равно > Больше < Меньше > Больше или равно <= Меньше или равно
К числу логических относятся операторы, приведенные ниже.
Результатом выполнения оператора отношения или логического оператора являет ся логическое значение типа bool.
В целом, объекты можно сравнивать на равенство или неравенство, используя опе раторы отношения == и !=. А операторы сравнения <, >, <= или >= могут применяться только к тем типам данных, которые поддерживают отношение порядка. Следователь но, операторы отношения можно применять ко всем числовым типам данных. Но зна чения типа bool могут сравниваться только на равенство или неравенство, поскольку истинные (true) и ложные (false) значения не упорядочиваются. Например, сравне ние true > false в C# не имеет смысла.
Операнды логических операторов должны относиться к типу bool, а результат вы полнения логической операции также относится к типу bool. Логические операторы &, |, ^ и ! поддерживают основные логические операции И, ИЛИ, исключающее ИЛИ и НЕ в соответствии с приведенной ниже таблицей истинности. p q p & q p | q p ^ q |P false false false false false true true false false true true false false true false true true true true true true true false false
Как следует из приведенной выше таблицы, результатом выполнения логической операции исключающее ИЛИ будет истинное значение (true), если один и только один ее операнд имеет значение true.
Ниже приведен пример программы, демонстрирующий применение нескольких операторов отношения и логических операторов. // Продемонстрировать применение операторов // отношения и логических операторов. using System; class RelLogOps { static void Main() { int i, j; bool b1, b2; i = 10; j = 11; if(i < j) Console.WriteLine("i < j"); if(i <= j) Console.WriteLine("i <= j"); if(i != j) Console.WriteLine("i != j"); if(i == j) Console.WriteLine("Нельзя выполнить"); if(i >= j) Console.WriteLine("Нельзя выполнить"); if(i > j) Console.WriteLine("Нельзя выполнить"); b1 = truer b2 = false; if(b1 & b2) Console.WriteLine("Нельзя выполнить"); if(!(b1 & b2)) Console.WriteLine("!(b1 & b2) — true"); if(b1 | b2) Console.WriteLine("b1 | b2 - true"); if(b1 ^ b2) Console.WriteLine("bl ^ b2 — true"); } }