246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 15
Текст из файла (страница 15)
Однако в строке 12 также содержится оператор if, который возвращает true, есливведенноечислонебольше100.Еслижеэточислобольше100,выполняетсястрока13.Если введенное число меньше 10, оператор if в строке 11 возвратит false. В этом случаедолжно выполниться выражение за оператором else (строка 15), которое выводит на экрансоответствующее сообщение. Но оказывается, что если ввести число меньше 10, то программапростозавершитсвоюработу.Судяпоотступу,операторelseвстроке14образуетединуюконструкциюсоператоромifвстроке 11. Но в действительности оператор else связан с оператором if в строке 12, поэтомупрограммабудетработатьнетак,какпланировалпрограммист.С точки зрения компилятора в этой программе на языке C++ нет никаких ошибок.Программа не работает как хотелось из-за логической ошибки.
Более того, даже притестированииэтойпрограммыможетсоздатьсявпечатление,чтоонаработаетправильно.Ведьпривводечислабольше100программаработаетнормальноидефектнепроявляется.Влистинге4.9показано,какможноисправитьэтуошибкуспомощьюфигурныхскобок.Листинг4.9.Примернадлежащегоиспользованияфигурныхскобоквконструкциисоператоромif1://Листинг4.9.Примернадлежащегоиспользования2://фигурныхскобокдлявложенныхоператоровif3:#include<iostream.h>4:intmain()5:{6:intx;7:cout<<"Enterаnumberlessthan10orgreaterthan100:";8:cin>>x;9:cout<<"\n";10:11:if(x>=10)12:{13:if(x>100)14:cout<<"Morethan100,Thanks!\n";15:}16:else//теперьвсеясно!17:cout<<"Lessthan10,Thanks!\n";18:return0;19:}Результат:Enteranumberlessthan10orgreaterthan100:20Фигурныескобки,поставленныевстроках12и15,превращаютвсе,чтостоитмеждуними,в одно выражение, и теперь оператор else в строке 16 явно связан с оператором if, стоящим встроке11,какибылозадумано.Пользовательввелчисло20,поэтомуоператорifвстроке11возвратилзначениеtrue;однакооператорifвстроке13возвратилfalse,поэтомусообщениенебыловыведенонаэкран.Былобылучше, если бы программист использовал еще один оператор else после строки 14, которыйвыводилбысообщениеотом,чтовведенноечислонеотвечаеттребованиям.Примечание:Программы,приведенныевэтойкниге,написаныдлядемонстрациичастныхвопросов,рассматриваемыхвданномразделе.Онинамереннонаписаныкакможнопроще;приэтом не ставилась цель предусмотреть все возможные ошибки, как это делается впрофессиональныхпрограммах.ЛогическиеоператорыДовольно часто у нас возникает необходимость проверять не одно условное выражение, асразунесколько.Например,правдали,чтоxбольшеу,атакжечтоубольшеz?Нашапрограмма,прежде чем выполнить соответствующее действие, должна установить, что оба эти условияистиннылибоодноизнихложно.Представьте себе высокоорганизованную сигнальную систему, обладающую следующейлогикой.
Если сработала установленная на двери сигнализация И время суток после шестивечера, И сегодня НЕТ праздника ИЛИ сегодня выходной, нужно вызывать полицию. ДляпроверкивсехусловийнужноиспользоватьтрилогическихоператораC++.Ониперечисленывтабл.4.2.Таблица4.2.ЛогическиеоператорыЛогическоеИЛогическийоператорИвычисляетдвавыражения,иеслиобавыражениявозвращаютtrue,тоиоператорИтакжевозвращаетtrue.Еслиправдато,чтовыголодны,Иправдато,чтоувасесть деньги, значит, справедливо и то, что вы можете пойти в супермаркет и купить себе что-нибудьнаобед.Например,логическоевыражениеif((x==5)&&(у==5))возвратит значение true, если и обе переменные — x и у — равны 5.
Это же выражениевозвратитfalse,еслихотябыоднаизпеременныхнеравна5.Обратитевнимание,чтовыражениевозвращаетtrueтольковтомслучае,еслиистинныобеегочасти.Логический оператор И обозначается двумя символами &&. Одиночный символ &соответствуетсовсемдругомуоператору,окоторомпойдетречьназанятии21.ЛогическоеИЛИЛогическийоператорИЛИтакжевычисляетдвавыражения.Еслилюбоеизнихистинно,тоиоператорИЛИвозвращаетtrue.ЕслиувасестьденьгиИЛИувасестькредитнаякарточка,выможетеоплатитьсчет.Приэтомнетнеобходимостивсоблюдениидвухусловийсразу:иметьиденьги,икредитнуюкарточку.Вамдостаточновыполненияодногоизних(хотяитоидругое—ещелучше).Например,выражениеif((x==5)||(у==5))возвратит значение true, если либо значение переменной x, либо значение переменной у,либоониобаравны5.Обратите внимание: логический оператор ИЛИ обозначается двумя символами 11.Оператор, обозначаемый одиночным символом |, — это совсем другой оператор, о которомпойдетречьназанятии21.ЛогическоеНЕТЛогическийоператорНЕТвозвращаетзначениеtrue,еслитестируемоевыражениеявляетсяложным(имеетзначениеfalse).Инаоборот,еслитестируемоевыражениеявляетсяистинным,тооператорНЕТвозвратитfalse!Например,выражениеif(!(x==5))возвратит значение true только в том случае, если x не равно числу 5.
Это же выражениеможнозаписатьипо-другому:if(x!=5)ВычислениепосокращеннойсхемеПредположим,компиляторуповстречалосьследующеелогическоевыражение:if((x==5)&&(у==5))Втакомслучаекомпиляторсначалаоценитпервоевыражение(x==5)и,еслионовозвратитfalse (т.е. x не равно числу 5), не станет вычислять второе выражение (у == 5), поскольку дляистинности всего выражения с оператором И нужно, чтобы обе его составляющие былиистинными.Аналогично,есликомпиляторуповстречаетсявыражениесоператоромИЛИif((x==5)||(у==5))ипервоевыражениеокажетсяистинным(x==5),токомпилятортакженестанетвычислятьвторое выражение (у == 5), поскольку ему достаточно одного истинного результата, чтобыпризнатьистиннымвсевыражение.ПриоритетыоператоровотношенийОператоры отношений и логические операторы используются в выражениях языка C++ ивозвращают значения true или false. Подобно всем другим операторам, им присущ некоторыйуровень приоритета (см.
приложение А), который определяет порядок вычисления операторовотношений. Этот момент нужно обязательно учитывать при определении значения такоговыражения,какif(x>5&&у>5||2>5)В данном случае о намерениях программиста можно только догадываться. Возможно, онхотел,чтобыэтовыражениевозвращалозначениеtrue,еслиxиубольше5илиеслиzбольше5.Сдругойстороны,можетбыть,программистхотел,чтобыэтовыражениевозвращалоtrueтольковтомслучае,еслиxбольше5илибоу,либоzбольше5.Если x равен 3, а у и z оба равны 10, то при использовании первой интерпретациинамерений программиста это выражение возвратит значение true (z больше 5, поэтомуигнорируем значения x и у), но при использовании второй интерпретации вернется значениеfalse (oHp не может дать значение true, поскольку для этого требуется, чтобы значение x былобольше 5, а после установления этого факта результат вычисления выражения справа отоператора && не важен, ведь для истинности всего выражения обе его части должны бытьистинными).Разобраться в приоритетах операторов в подобных выражениях довольно сложно, поэтомустоит воспользоваться круглыми скобками — ведь с их помощью можно не только изменитьпоследовательность выполнения операторов, обусловленную их приоритетами, но и сделатьяснымиподобныезапутанныевыражения:if((x>5)&&(у>5||z>5))При использовании предложенных выше значений это выражение возвращает значениеfalse.
Поскольку оказалось, что x (его значение равно 3) не больше 5, то выражение слева отоператора И возвращает false, а следовательно, и все выражение целиком тоже возвратит false.Помните, что оператор И возвращает true только в том случае, когда обе части выражениявозвращают true. Например, ваш вкус можно считать хорошим только в том случае, если онадетойнавасвещиможносказать,чтоонамоднаяичтовамонаидет.Примечание:Часто дополнительные круглые скобки стоит использовать только длячеткого определения того, что именно вы хотите сгруппировать. Помните, что цельпрограммиста—написатьпрограмму,котораяпрекрасноработает,атакжелегкочитаетсяипонимается.ПодробнееобистинеилжиВ языке C++ нуль эквивалентен значению false, а все другие числовые значенияэквивалентны значению true. Поскольку любое выражение всегда имеет значение, многиепрограммисты пользуются преимуществами этой эквивалентности значений в выраженияхусловияоператораif.Такоевыражение,какif(x)//еслиxнеравеннулю,тоусловиеистинноx=0;можно читать следующим образом: если переменная x имеет ненулевое значение,устанавливаемееравнойнулю.Чтобысделатьсмыслэтоговыраженияболееочевидным,можнозаписатьеготак:if(x!=0)//еслиxненульx=0;Обавыраженияодинаковоправомочны,нопоследнеепонятнее.Иещеодинмомент.Чтобыпрограмма не превратилась в сплошное шаманство, лучше все-таки проверять истинностьнекоторыхлогическихусловий,анеравенствовыражениянулю.Следующиедвавыражениятакжеэквивалентны:if(!x)//истинно,еслиxравеннулюif(x==0)//еслиxравеннулюОднако, второе выражение проще для понимания и гораздо очевиднее, поскольку явнопроверяетсяматематическоезначениепеременнойx.Рекомендуется: Используйте круглые скобки, чтобы более четко указать порядоквыполненияоператоровилиизменитьихприоритеты.Используйтефигурныескобкивконструкцияхсвложеннымиоператорамиif,чтобычеткоопределитьвзаимосвязимеждучастямиконструкциииизбежатьошибок.Нерекомендуется:Неиспользуйтевыражениеif(x)какэквивалентвыраженияif(x!=0).Последнийвариантпредпочтительнее,посколькучетчевидналогикапроверкиусловия.Неиспользуйтевыражениеif(!х)какэквивалентвыраженияif(x==0).Последнийвариантпредпочтительнее,посколькучетчевидналоткапроверкиусловия.УсловныйоператорУсловныйоператор(?:)—этоединственныйоператорвязыкеC++,которыйработаетсразустремяоперандами.Синтаксисиспользованияусловногооператораследующий:(выражение1)?(выражение2):(выражениеЗ)Эта строка читается таким образом: если выражение1 возвращает true, то выполняетсявыражение2, в противном случае выполняется выражениеЗ.
Обычно возвращаемое значениеприсваиваетсянекоторойпеременной.Влистинге4.10показаноиспользованиеусловногооператоравместооператораif.Листинг4.10.Примериспользованияусловногооператора1://Листинг4.10.Примериспользованияусловногооператора2://3:#include<iostream.h>4:intmain()5:{6:intx.у,z;7:cout<<"Entertwonumbers.\n";8:cout<<"First:";9:cin>>x;10:cout<<"\nSecond:";11:cin>>у;12:cout<<"\n";13:14:if(x>у)15:z=x;16:else17:z=у;18:19:cout<<"z:"<<z;20:cout<<"\n";21:22:z=(x>у)?x:у;23:24:cout<<"z:"<<z;25:cout<<"\n";26:return0;27:}Результат:Entertwonumbers.First:5Second:8z:8z:8Анализ:Сначаласоздаетсятрицелочисленныепеременные:x,уиz.Значенияпервыхдвухвводятсяпользователем.Затемвстроке14выполняетсяинструкцияif,котораяпозволяетузнать,какое из введенных значений больше, причем выявленное большее значение присваиваетсяпеременнойz.Этозначениевыводитсянаэкранвстроке19.Тужесамуюпроверкувыполняетвстроке22условныйоператориприсваиваетпеременнойzбольшеезначение.Ончитаетсяследующимобразом:"Еслиxбольшеу,возвращаемзначениеx;впротивномслучаевозвращаемзначениеу".Возвращаемоезначениеприсваиваетсяпеременнойz.Этозначениевыводитсянаэкранвстроке24.Каквидите,инструкция,содержащаяусловныйоператор,являетсяболеекороткимэквивалентоминструкцииif...else.РезюмеДанноезанятиеохватываетбольшойобъемматериала.Выузнали,чтопредставляютсобойоператорыивыражениявязыкеC++,какиеразновидностиоператоровсуществуютвC++икакработаетоператорif.Теперьвызнаете,чтоблоквыражений,заключенныйвнутрипарыфигурныхскобок,можноиспользоватьвместоодиночноговыражения.Вытакжеузнали,чтокаждоевыражениевозвращаетнекотороезначениеичтоэтозначениеможно проверить с помощью инструкции if или условного оператора.