Страница 23 из 188
Обратите внимание на последнюю строку приведенного выше результата. Когдацелое значение 10 сдвигается влево тридцать раз подряд, информация теряется, поскольку двоичные разряды сдвигаются за пределы представления чисел для типа int.В данном случае получается совершенно "непригодное" значение, которое оказываетсяк тому же отрицательным, поскольку в результате сдвига в старшем разряде, используемом в качестве знакового, оказывается 1, а следовательно, данное числовое значениедолжно интерпретироваться как отрицательное. Этот пример наглядно показывает,что применять операторы сдвига для умножения иди деления на 2 следует очень аккуратно. (Подробнее о типах данных со знаком и без знака см. в главе 3.)Поразрядные составные операторы присваивания
Все двоичные поразрядные операторы могут быть использованы в составных операциях присваивания. Например, в двух приведенных ниже операторах переменнойх присваивается результат выполнения операции исключающее ИЛИ над первоначальным значением переменной х и числовым значением 127.х = х ^ 127;х ^= 127;Оператор ?
Оператор ? относится к числу самых примечательных в С#. Он представляет собой условный оператор и часто используется вместо определенных видов конструкцийif-then-else. Оператор ? иногда еще называют тернарным, поскольку для него требуются три операнда. Ниже приведена общая форма этого оператора.Выражение! ? Выражение2 : Выражение3;
Здесь Выражение1 должно относиться к типу bool, а Выражение2 и Выражение3 —к одному и тому же типу. Обратите внимание на применение двоеточия и его местоположение в операторе ?.
Значение выражения ? определяется следующим образом. Сначала вычисляетсяВыражение1. Если оно истинно, то вычисляется Выражение2, а полученный результатопределяет значение всего выражения ? в целом. Если же Выражение1 оказываетсяложным, то вычисляется Выражение3, и его значение становится общим для всего выражения ?. Рассмотрим следующий пример, в котором переменной absval присваивается значение переменной val.absval = val < 0 ? -val : val; // получить абсолютное значение переменной val
В данном примере переменной absval присваивается значение переменной val,если оно больше или равно нулю. Если же значение переменной val отрицательно, топеременной absval присваивается результат отрицания этого значения, что в итогедает положительное значение.
Ниже приведен еще один пример применения оператора ?. В данной программеодно число делится на другое, но при этом исключается деление на нуль.// Исключить деление на нуль, используя оператор?.using System;class NoZeroDiv { static void Main() { int result; for(int i = -5; i < 6; i++) { result = i != 0 ? 100 / i : 0; if (i ! = 0) Console.WriteLine("100 / " + i + " равно " + result); } }}
Выполнение этой программы дает следующий результат.100 / -5 равно -20100 / -4 равно -25100 / -3 равно -33100 / -2 равно -50100 / -1 равно -100100 / 1 равно 100100 / 2 равно 50100 / 3 равно 33100 / 4 равно 25100 / 5 равно 20
Обратите особое внимание на следующую строку из приведенной выше программы.result = i != 0 ? 100 / i : 0;
В этой строке переменной result присваивается результат деления числа 100 назначение переменной i. Но это деление осуществляется лишь в том случае, если значение переменной i не равно нулю. Когда же оно равно нулю, переменной resultприсваивается значение, обнуляющее результат.
Присваивать переменной результат выполнения оператора ? совсем не обязательно. Например, значение, которое дает оператор ?, можно использовать в качестве аргумента при вызове метода. А если все выражения в операторе ? относятся к типу bool,то такой оператор может заменить собой условное выражение в цикле или оператореif. В приведенном ниже примере программы выводятся результаты деления числа100 только на четные, ненулевые значения.// Разделить только на четные, ненулевые значения.using System;class NoZeroDiv2 { static void Main() { for(int i = -5; i < 6; i++) if(i != 0 ? (i%2 == 0) : false) Console.WriteLine("100 / " + i + " равно " + 100 / i); }}
Обратите внимание на оператор if в приведенной выше программе. Если значениепеременной i равно нулю, то оператор if дает ложный результат. А если значениепеременной i не равно нулю, то оператор if дает истинный результат, когда значениепеременной i оказывается четным, и ложный результат, если оно нечетное. Благодаряэтому допускается деление только на четные и ненулевые значения. Несмотря на точто данный пример служит лишь для целей демонстрации, подобные конструкциииногда оказываются весьма полезными.Использование пробелов и круглых скобок
В выражении на C# допускается наличие символов табуляции и пробелов, благодаря которым оно становится более удобным для чтения. Например, оба приведенныхниже выражения, по существу, одинаковы, но второе читается легче.х=10/у*(127+х);х = 10 / у * (127 + х);
Скобки могут служить для группирования подвыражений, по существу, повышаяпорядок предшествования заключенных в них операций, как в алгебре. Применениелишних или дополнительных скобок не приводит к ошибкам и не замедляет вычисление выражения. Поэтому скобки рекомендуется использовать, чтобы сделать болееясным и понятным порядок вычисления как для самого автора программы, так и длятех, кто будет разбираться в ней впоследствии. Например, какое из двух приведенныхниже выражение легче читается?х = у/3-34*temp+127;х = (у/3) - (34*temp) + 127;Предшествование операторов
В табл. 4.2 приведен порядок предшествования всех операторов в С#: от самого высокого до самого низкого. В таблицу включен ряд операторов, рассматриваемых далеев этой книге.Наивысший порядок()[].++ (постфиксный)-- (постфиксный)checkednewsizeoftypeofunchecked!~(приведение типов)+ (унарный)- (унарный)++ (префиксный)-- (префиксный)*/%<<>><><=>=is==!=&^|&&||???:=op==>Наинизший порядок
ГЛАВА 5. Управляющие операторы
В этой главе речь пойдет об операторах, управляющихходом выполнения программы на С#. Управляющиеоператоры разделяются на три категории: операторывыбора, к числу которых относятся операторы if и switch,итерационные операторы, в том числе операторы циклаfor, while, do-while и foreach, а также операторы перехода: break, continue, goto, return и throw. За исключением оператора throw, который является неотъемлемойчастью встроенного в C# механизма обработки исключительных ситуаций, рассматриваемого в главе 13, все остальные управляющие операторы представлены в этой главе.Оператор if
Оператор if уже был представлен в главе 2, а здесь онрассматривается более подробно. Ниже приведена полнаяформа этого оператора:if(условие) оператор;else оператор;
где условие — это некоторое условное выражение, a опe-ратор — адресат операторов if и else. Оператор elseне является обязательным. Адресатом обоих операторов,if и else, могут также служить блоки операторов. Нижеприведена общая форма оператора if, в котором используются блоки операторов.if(условие){последовательность операторов}else{последовательность операторов}
Если условное выражение оказывается истинным, то выполняется адресат оператора if. В противном случае выполняется адресат оператора else, если таковой существует. Но одновременно не может выполняться и то и другое. Условное выражение,управляющее оператором if, должно давать результат типа bool.
Ниже приведен пример простой программы, в которой операторы if и elseиспользуются для того, чтобы сообщить, является ли число положительным илиотрицательным.// Определить, является ли числовое значение положительным илиотрицательным.using System;class PosNeg { static void Main() { int i; for(i=-5; i <= 5; i++) { Console.Write("Проверка " + i + "); if(i < 0) Console.WriteLine("отрицательное число”); else Console.WriteLine("положительное число"); } }}