Управление порядком выполнения У всех программ на С#, которые рассматривались до сих пор, имеется одна об- щая черта. Во всех случаях выполнение кода происходило последовательно сверху вниз, строка за строкой, без каких-либо пропусков. Однако если бы приложения всегда выполнялись таким образом, то наши возможности были бы сильно огра- ничены. В настоящей главе мы изучим два способа управления порядком выполнения программ, т. е. последовательностью выполняемых в программе на С# строк. Вот эти способы: • Ветвление — выполнение кода обусловлено результатами предшествующих вычислений, например: "выполнить этот код только в том случае, если значение переменной myval меньше 10". • Использование циклов — повторяющееся выполнение одних и тех же операторов (определенное количество раз или до тех пор, пока не выполнится контрольное условие). Оба способа предполагают использование булевой логики. В предыдущей главе вы познакомились с типом bool, однако практически не использовали его. В этой главе мы собираемся наверстать упущенное и начнем с рассмотрения булевой ло- гики, чтобы потом использовать ее в сценариях управления порядком выполнения программ. Булева логика Тип bool, представленный в предыдущей главе, может принимать одно из двух значений: true (истина) или false (ложь). Этот тип очень часто применяется для записи результата выполнения какой-либо операции, с тем, чтобы мы могли вы- полнить какие-либо определяемые им действия. В частности, тип bool использует- ся для хранения результатов сравнения. В порядке исторического отступления необходимо вспомнить (и отдать ему дань уважения) английского математика Джорджа Буля (George Boole), работы которого, написанные в середине XIX века, послужили основой для создания булевой логики. 48 Глава 4 В качестве примера давайте рассмотрим ситуацию, приведенную в начале этой главы, когда выполнять код нужно только при значении переменной myval мень- ше 10. Для этого необходимо владеть некоторым способом, позволяющим опре- делять, является ли утверждение "myval меньше 10" правдой или ложью; т.е. необходимо получить результат логического сравнения. Логическое сравнение требует применения логических операторов сравнения (также известных под именем операторов отношения), которые приведены в рас- положенной ниже таблице. В этой таблице переменная vari во всех случаях имеет тип bool, а типы переменных var2 и var3 меняются. Оператор Тип Пример выражения Результат Бинарный Бинарный Бинарный Бинарный Бинарный Бинарный varl = var2 == var3; varl = var2 != var3; varl = var2 < var3; varl = var2 > var3; varl = var2 <= var3; varl = var2 >= var3; Переменной varl присваивается значение true в том случае, если переменная var2 равна переменной var3, и значение false в противном случае Переменной varl присваивается значение true в том случае, если переменная var2 не равна переменной var3, и значение false в противном случае Переменной varl присваивается значение true в том случае, если переменная var2 меньше переменной var3, и значение false в противном случае Переменной varl присваивается значение true 'в том случае, если переменная var2 больше переменной var3, и значение false в противном случае Переменной varl присваивается значение true в том случае, если переменная var2 меньше или равна переменной var3, и значение false в противном случае Переменной varl присваивается значение true в том случае, если переменная var2 больше или равна переменной var3, и значение false в противном случае В программе мы можем использовать эти операторы для численных значений следующим образом: bool isLessThanio; isLessThanio = rayVal < 10; В результате выполнения этого кода переменной isLessThanio будет присвоено значение true в том случае, если значение переменной myval меньше 10, а в про- тивном случае — значение false. Операторы сравнения могут использоваться также и для переменных других типов, например, для строк: bool isKarli; isKarli = myString == "Karli"; В данном случае переменной isKarli будет присвоено значение true только при условии, что строка, содержащаяся в переменной mystring, имеет вид Управление порядком выполнения 49 Аналогичным образом можно поступать и с логическими переменными: Щ ' к - . - ' • • • • : • . ••• '. • • ' •:• • • •. :•::• • У. : '' '•[ У •;: . \ ' : \ • :'Ж "' У-У У.<: ' Ш У У isTrue = my Bool == true; Однако в этом случае допускается использование только операторов — — и !—. Распространенной ошибкой является безосновательное предположение, что если vail < vai2 есть ложь, то vail > vai2 — истина. Если vail == vai2, оба предыдущих выражения будут ложными. Автор специально упоминает об этой частой ошибке, поскольку сам допускал ее в прошлом. Существуют и некоторые другие операторы, специально предназначенные для работы с логическими значениями: Оператор Тип Пример выражения Результат i Унарный varl • I var2; Переменной varl присваивается значение true в том случае, если переменная var2 имеет значение false, и значение false, если значение var2 — true (операция "логическое не" (NOT)) & Бинарный varl = var2 & var3; Переменной varl присваивается значение true в том случае, если обе переменные var2 и var3 имеют значение true, и значение false в противном случае (операция "логическое и" (AND)) I Бинарный varl = var2 I var3; Переменной varl присваивается значение true в том случае, если хотя бы одна из переменных — var2 или var3 (или обе) — имеет значение true, и значение false в противном случае (операция "логическое или" (OR)) Бинарный varl = var2 Л var3; Переменной varl присваивается значение true в том случае, если одна из переменных — var2 или var3, но не обе одновременно — имеет значение true, и значение false в противном случае (операция "исключающее или" (XOR)) Теперь мы можем записать последний пример следующим образом: '{ШМ'7': : : . : :•:. U У. ?Ш£Ш^£ШШ&-ЖШУ ТЖ У У ' Ч Щ Ш' 'Ж '•; isTrue « myBool & true; Для операторов & и | существуют аналоги: Оператор Тип Пример выражения Результат && Бинарный varl = var2 && v a r 3 ; Переменной v a r l присваивается значение t r u e в том случае, если обе переменные var2 и v a r 3 имеют значение t r u e , и значение f a l s e в про- тивном случае (операция "логическое и" (AND)) I I Бинарный varl = var2 I I v a r 3 ; Переменной v a r l присваивается значение t r u e в том случае, если одна из переменных, var2 или v a r 3 (или обе), имеет значение t r u e , и значение f a l s e в противном случае (операция "логическое или" (OR)) 50 Глава 4 Результат выполнения этих операций в точности соответствует результату вы- полнения операций & и |, однако существует одно важное отличие; оно заключает- ся в способе достижения результата, позволяющем в некоторых случаях ускорить операцию. Оба эти оператора рассматривают значение своего первого операнда (в приведенной выше таблице это var2) и в определенных случаях могут вообще обходиться без обработки второго операнда (в нашем примере var3). Если значение первого операнда оператора && — false, то нет необходимости рассматривать значение второго операнда, поскольку результатом все равно будет значение false. Аналогично оператор || вернет значение true, если его первый операнд имеет значение true, независимо от значения второго операнда. При вы- полнении операторов & и | всегда происходит вычисление обоих операндов. С учетом этого при использовании операторов && и || вместо & и | можно ожи- дать небольшого увеличения быстродействия. Выгода будет особенно ощутима в тех приложениях, где задействовано много таких операторов. Существует эмпириче- ское правило, согласно которому при наличии возможности всегда следует исполь- зовать операторы && и ||.