Г. Шилдт - Полный справочник по C# (1160789), страница 19
Текст из файла (страница 19)
Рассмотрим следующую инструкцию:| х = х + 10;Используя составной оператор присваивания, ее можно переписать в таком виде:х += 10;Пара операторов += служит указанием компилятору присвоить переменной х сумму текущего значения переменной х и числа 10.
А вот еще один пример. Инструкция| х = х - 100;аналогична такой:| х -= 100;Обе эти инструкции присваивают переменной х ее прежнее значение, уменьшенное на 100.Глава 4. Операторы89Составные версии операторов присваивания существуют для всех бинарных операторов (т.е. для всех операторов, которые работают с двумя операндами).
Общая формаих записи такова:переменная ор = выражение;Здесь элемент ор означает конкретный арифметический или логический оператор,объединяемый с оператором присваивания.Возможны следующие варианты объединения операторов.+=-=*=/=%=&=1=Поскольку составные операторы присваивания выглядят короче своих несоставныхэквивалентов, то составные версии часто называют укороченными операторами присваивания.Составные операторы присваивания обладают двумя заметными достоинствами.Во-первых, они компактнее своих "длинных" эквивалентов.
Во-вторых, их наличиеприводит к созданию более эффективного кода (поскольку операнд в этом случае вычисляется только один раз). Поэтому в профессионально написанных Сопрограммахвы часто встретите именно составные операторы присваивания.Поразрядные операторыВ С# предусмотрен набор поразрядных операторов, которые расширяют областиприложения языка С#. Поразрядные операторы действуют непосредственно на разряды своих операндов. Они определены только для целочисленных операндов и не могут быть использованы для операндов типа bool, f l o a t или double.Поразрядные операторы предназначены для тестирования, установки или сдвигабитов (разрядов), из которых состоит целочисленное значение. Поразрядные операторы очень часто используются для решения широкого круга задач программированиясистемного уровня, например, при опросе информации о состоянии устройства илиее формировании.
Поразрядные операторы перечислены в табл. 4.1.Таблица 4.1. Поразрядные операторыОператорЗначение&Поразрядное ИIПоразрядное ИЛИПоразрядное исключающее ИЛИ»«Сдвиг вправоСдвиг влевоДополнение до 1 (унарный оператор НЕ)Поразрядные операторы И, ИЛИ, исключающее ИЛИ и НЕПоразрядные операторы И, ИЛИ, исключающее ИЛИ и НЕ обозначаются символами &, |, л и ~, соответственно.
Они выполняют те же операции, что и их логические эквиваленты, описанные выше. Различие состоит лишь в том, что поразрядныеоперации работают на побитовой основе. В следующей таблице показан результат выполнения каждой поразрядной операции для всех возможных сочетаний операндов(нулей и единиц).90Часть I. Язык С#я0011р0101р & qР! ЯРАЯ~J0001011001111100Поразрядный оператор И можно представить как способ подавления битовой информации.
Это значит, что 0 в любом операнде обеспечит установку в 0 соответствующего бита результата. Вот пример:1101 ООП1010 1010&1000 0010В следующей программе демонстрируется использование поразрядного оператора& для получения четных чисел из нечетных. Это реализуется посредством подавления(установки в нуль) младшего разряда числа. Например, число 9 в двоичном коде представляется числом 0000 1001.
После обнуления младшего разряда получается число 8(0000 1000 в двоичном коде).// Использование поразрядного оператора И для// "превращения" любого числа в четное.using System;class MakeEven {public s t a t i c void Main() {ushort num;ushort i ;for(i = 1; i <= 10; i++) {num = i ;Console.WriteLine("num: " + num);num = (ushort) (num & OxFFFE); // num & 1111 1110Console.WriteLine("num после сброса младшего бита: "+ num + " \ n " ) ;}Результат выполнения этой программы имеет следующий вид:num: 1num после сброса младшего бита: 0num: 2num после сброса младшего бита: 2num: 3num после сброса младшего бита: 2num: 4num после сброса младшего бита: 4num: 5Глава 4.
Операторы91num после сброса младшего бита: 4num: бnum после сброса младшего бита: бnum: 7num после сброса младшего бита: бnum: 8num после сброса младшего бита: 8,num: 9num после сброса младшего бита: 8num: 10num после сброса младшего бита: 10Значение OxFFFE, используемое в этой программе, в двоичном коде представляется числом 1111 1111 1111 1110.
Таким образом, операция num & OxFFFE оставляет всебиты неизменными за исключением младшего, который устанавливается в нуль. Поэтому любое четное число, пройдя через это "чистилище", остается четным, а любоенечетное "выходит" из него уже четным (за счет уменьшения на единицу).Оператор И также используется для определения значения разряда. Например,следующая программа определяет, является ли заданное число нечетным.// Использование поразрядного оператора И для// определения, является ли число нечетным,using System;class IsOdd {public static void Main() {ushort num;num = 10;if((num & 1) == 1)Console.WriteLine("Этот текст не будет отображен.");num = 11;if((num & 1) == 1)Console.WriteLine(num + " —нечетное число.");Результат выполнения этой программы выглядит так:1 11 — нечетное число.В обеих инструкциях i f выполняется операция И для значения переменной num ичисла 1.
Если младший бит переменной num установлен (т.е. равен единице), результат операции num & 1 также будет равен единице. В противном случае результат будетравен нулю. Условие инструкции i f выполнится только в случае, если анализируемоечисло окажется нечетным.Возможности поразрядного тестирования, которые предоставляет поразрядныйоператор &, можно использовать для создания программы, которая отображает значение типа b y t e в двоичном формате. Рассмотрим один из возможных вариантов решения этой задачи.92Часть I.
Язык С#// Отображение значений битов, составляющих байт,using System;class ShowBits {public s t a t i c void Main() {int t ;byte val;val = 123;for(t=128; t > 0; t = t/2) {if((val & t) != 0) Console.Write ("1 " ) ;if((val & t) == 0) Console.Write ("0 ") ;Вот как выглядит результат выполнения этой программы:0 1 1 1 1 0 1 1В цикле for с помощью поразрядного оператора И последовательно тестируетсякаждый бит переменной val. Если оказывается, что этот бит установлен, отображается цифра 1, в противном случае — цифра 0.Поразрядный оператор ИЛИ, в противоположность поразрядному И, удобно использовать для установки нужных битов в единицу. При выполнении операции ИЛИналичие в операнде бита, равного 1, означает, что в результате соответствующий биттакже будет равен единице.
Вот пример:1101 ООП1010 10101111 1011С помощью поразрядного оператора ИЛИ рассмотренную выше программу получения четных чисел легко превратить в программу получения нечетных чисел.// Использование поразрядного оператора ИЛИ для// "превращения" любого числа в нечетное,using System;c l a s s MakeOdd {public s t a t i c void Main() {ushort num;ushort i ;f o r ( i = 1; i <= 10; i++) {num = i ;Console.WriteLine("num: " + num);num = (ushort) (num | 1 ) ; // num | 0000 0001Console.WriteLine("num после установки младшего бита: "+ num + " \ n " ) ;Глава 4.
Операторы93Результат выполнения этого варианта программы таков:num: 1num после установки младшего бита: 1num: 2num после установки младшего бита: 3num: 3num после установки младшего бита: 3num: 4num после установки младшего бита: 5num: 5num после установки младшего бита: 5num: бnum после установки младшего бита: 7num: 7num после установки младшего бита: 7num: 8num после установки младшего бита: 9num: 9num после установки младшего бита: 9num: 10num после установки младшего бита: 11Работа этой программы основана на выполнении поразрядной операции ИЛИ между каждым числом, генерируемым в цикле for, и числом 1, которое в двоичном коде представляется как 0000 0001.
Таким образом, 1 — это значение, у которого установлен только один младший разряд. Если это значение является одним из операндовоперации ИЛИ, то результат выполнения этой операции совпадет со вторым операндом за исключением его младшего разряда, который станет равным единице (а все остальные при этом не изменятся). Следовательно, любое четное число, "пройдя" черезоперацию ИЛИ, увеличится на единицу, т.е. станет нечетным.Поразрядное исключающее ИЛИ (XOR) устанавливает в единицу бит результататолько в том случае, если соответствующие биты операндов отличаются один от другого, т.е.
не равны. Вот пример:0111 11111011 10011100 0110Оператор XOR обладает одним интересным свойством, которое позволяет использовать его для кодирования сообщений. Если выполнить операцию XOR между значением х и значением Y, а затем снова выполнить операцию XOR между результатомпервой операции и тем же значением Y, получим исходное значение х. Это значит,что после выполнения двух операцийR1R2= X= RlАAY;Y;значение R2 совпадет со значением х. Таким образом, в результате выполнения двухпоследовательных операций XOR, использующих одно и то же значение (Y), получается исходное значение (х).
Этот принцип можно использовать для создания простой94Часть I. Язык С#программы шифрования, в которой некоторое целочисленное значение — ключ —служит для кодирования и декодирования сообщения, состоящего из символов. Дляшифрования сообщения операция исключающего ИЛИ применяется первый раз, адля его дешифровки — второй. Реализуем этот простой способ шифрования в следующей программе:// Использование оператора XOR для шифрования/ / и дешифрирования сообщения.u s i n g System;c l a s s Encode {p u b l i c s t a t i c void Main() {char chl = f H f ;char ch2 = ' i ' ;char ch3 = f ! f ;i n t key = 88;Console.WriteLine("Исходное сообщение: " +chl + ch2 + ch3);// Шифруем сообщение,chl - (char) (chl A key);ch2 = (char) (ch2 л key);ch3 = (char) (ch3 A key);Console.WriteLine("Зашифрованное сообщение: " +chl + ch2 + ch3);//chlch2ch3Дешифрируем сообщение,= (char) (chl A key);= (char) (ch2 A key);= (char) (ch3 л key);Console.WriteLine("Дешифрованное сообщение: " +chl + ch2 + ch3);Вот как выглядит результат выполнения этой программы:Исходное сообщение: Hi!Зашифрованное сообщение: >1уДешифрованное сообщение: Hi!Как видите, в результате выполнения двух операций XOR, использующих одно ито же значение ключа, получается исходное (дешифрованное) сообщение.Унарный оператор НЕ (или оператор дополнения до 1) инвертирует состояниевсех битов своего операнда.