|
|
Строка 1: |
Строка 1: |
− | В этой главе будут рассмотрены основные синтаксические конструкции, которые так или иначе присутствуют в любом современном языке программирования, будь то функциональный или объектно-ориентированный язык. Это констркции условного перехода и циклы. Без подобных конструкций (или их аналогов) невозможно написать программу, сколько-нибудь сложнее чем "Hello world".
| + | A few years ago I'd have to pay soomene for this information. |
− | | + | |
− | __TOC__
| + | |
− | | + | |
− | == Условный оператор ==
| + | |
− | | + | |
− | Условный оператор — это основа основ любого языка программирования. На основании условия, то есть значения некоторого выражения, принимается решение, куда следует двигаться программе. В основе всех условных операторов лежит булева логика, при которой любое утверждение сводится к двум понятиям: истина и ложь. Если условие истинно, то управление программы движется в одну сторону. Если условие ложно — в другую. Таким образом, в каждый момент времени делается выбор всего из двух направлений. Более сложные условия строятся путем последовательного прохождения элементарных, двоичных условий.
| + | |
− | | + | |
− | === Оператор if ===
| + | |
− | | + | |
− | В языке K++, для проверки условия служит оператор <tt>'''if'''</tt>, так же называемый условным оператором. Синтаксис этого оператора знаком наверное любому человеку, который имеет хоть какое-то представление о языках программирования:
| + | |
− | <source lang="kpp">
| + | |
− | if (/* выражение условия */) {
| + | |
− | /* тело оператора */
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | Если в коде программы встречается условный оператор, то первым делом происходит вычисление значения его условия — выражения, заключенного в круглые скобки. В качестве такого выражения, может быть указано любое выражение, которое возвращает значение. Если значение условного выражения можно трактовать как истину, то управление передается телу оператора, заключенному в фигурные скобки (в случае единственного выражения в теле оператора, фигурные скобки можно опустить). Если же значение условия ложно — управление передается следующему выражению, стоящему после условного оператора (то есть, тело оператора просто пропускается).
| + | |
− | | + | |
− | Истинным, считается любой существующий объект, а так же логические [[Типы операторов#Операторы сравнения|операторы сравнения и отношения]] (такие как <tt>==</tt>, <tt>!=</tt>, <tt><</tt> и т. д), если их значение истинно (то есть, объекты соответствуют указанному отношению), а так же специальное ключевое слово <tt>'''true'''</tt>, которое считается истинным всегда. Исключением является объект типа bool, имеющий в данный момент значение <tt>'''false'''</tt>.
| + | |
− | | + | |
− | Ложными, соответственно, считаются несозданные объекты (пустые указатели), а так же операторы отношения, если их значение ложно (объекты не соответствуют отношению). Ложными так же считаются объекты, соответствующие ключевым словам <tt>'''false'''</tt> и <tt>'''null'''</tt>. Опять же, исключением является объект типа bool, если он имеет значение <tt>'''true'''</tt>.
| + | |
− | | + | |
− | Для ясности приведем несколько выражений, а так же укажем соответствующие им логические значения:
| + | |
− | <source lang="kpp">
| + | |
− | //Выражение булево значение
| + | |
− | true true
| + | |
− | false false
| + | |
− | null false
| + | |
− | var x; x false
| + | |
− | var y; y = 1; true
| + | |
− | var int z; z true
| + | |
− | var bool x; false
| + | |
− | var bool x; x = true; true
| + | |
− | 0 true
| + | |
− | 1 true
| + | |
− | "hello world" true
| + | |
− | 0 == 1 false
| + | |
− | 5 < 6 true
| + | |
− | 2 > 3 false
| + | |
− | 5 >= 5 true
| + | |
− | 'a' != 'b' true
| + | |
− | </source>
| + | |
− | | + | |
− | Обратите внимание на следующие моменты:
| + | |
− | * Неинициализированная динамическая переменная ''x'' считается ложной (равна <tt>'''null'''</tt>)
| + | |
− | * Инициализированная динамическая переменная ''y'' считается истинной (объект создан)
| + | |
− | * Неинициализированная статическая переменная ''z'' считается истинной (объект создан)
| + | |
− | * Переменная типа <tt>bool</tt> имеет значение по умолчанию <tt>'''false'''</tt> (хотя объект создан)
| + | |
− | * 0, так же как любой другой созданный объект считается '''истиной''', в отличие от C++.
| + | |
− | * условие 5 >= 5 считается истиной, так как формулируется как "5 больше 5 '''или''' равно 5"
| + | |
− | | + | |
− | По поводу нуля следует поговорить отдельно. C++ не является в полной мере объектно-ориентированным языком, фактически, в нем ОО система является абстракцией, позволяющей оперировать все теми же понятиями стандартных типов данных и памяти, но на более высоком уровне. Все что мы имеем на этапе выполнения программы, это кусочки памяти, которые мы считаем объектами. Поскольку числа в нем являются совершенно определенной сущностью, подобные вольности возможны.
| + | |
− | | + | |
− | В языке К++ все наоборот. Все с чем он оперирует — это объекты. Провести грань между стандартными типами данных и пользовательскими невозможно. Числа, что фигурируют в программе так же являются объектами. Даже числовые константы которые записываются в выражениях — это тоже объекты (это уже было показано в [[Введение, или краткий обзор#Расширение классов|кратком обзоре]]). За основу логики языка принимается факт существования объекта. Если объекта не существует — значение ложно, если существует — истинно (кроме описанных выше исключений). Оператор <tt>'''if'''</tt> помимо чистой логики, служит для определения существования объекта. Получается, что при таком подходе, делать для нуля исключение нерационально, и более того — это может привести к ошибкам. Возьмем к примеру код:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | if (x) {
| + | |
− | /* код, соответствущий существованию переменной x */
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | Подразумевается, что тело оператора будет выполнено в случае, если передаваемый объект (вероятнее всего [[Переменные#Нетипированные (динамические) переменные|динамическая переменная]]) инициализирован и существует. Но что будет, если мы передадим в качестве объекта динамическую переменную, содержащую объект типа <tt>int</tt>, равный нулю? Если бы реализация языка обрабатывала значение 0 как ложь, то логика оператора <tt>'''if'''</tt> в частости и всей программы в целом, зависела бы от фактического значения переменной, а соответственно была бы неопределенной и даже непредсказуемой. Получалось бы, что для одних переменных, оператор работает одним образом, а для других — другим. Отладка подобной программы может занять многие часы. А все из-за одной условности.
| + | |
− | | + | |
− | Таким образом, можно заключить, что оператор <tt>'''if'''</tt> следует применять для проверки логического выражения, либо для проверки существования переменной. Если мы хотим проверить равенство переменной нулю, то это необходимо делать явно:
| + | |
− | <source lang="kpp">
| + | |
− | if (x == 0) {
| + | |
− | /* что нужно делать, если x равен 0 */
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | And I thought I was the seinsble one. Thanks for setting me straight.
| + | |
− | | + | |
− | === Оператор if-elsif-else ===
| + | |
− | | + | |
− | Существует так же третья форма условного оператора, которая позволяет проверять несколько условий в единой, более эффективной форме. Это конструкция <tt>'''if-elsif-else'''</tt>:
| + | |
− | <source lang="kpp">
| + | |
− | if (/* условие 1 */) {
| + | |
− | /* код, соответствущий истине условия 1*/
| + | |
− | } elsif (/*условие 2*/) {
| + | |
− | /* код, соответствущий истине условия 2*/
| + | |
− | ...
| + | |
− | } else {
| + | |
− | /* код, соответствущий лжи */
| + | |
− | }
| + | |
− | </source>
| + | |
− | Она работает так: сначала проверяется условие 1. Если оно истинно, то выполняется код в первом блоке, а затем управление выходит за рамки всей связки. Если условие 1 ложно, то проверяется условие 2, и т. д. Таким образом, вышеописанная конструкция функционально эквивалентна следующей конструкции, однако более компактна.
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | if (/* условие 1 */) {
| + | |
− | /* если условие 1 истинно */
| + | |
− | } else {
| + | |
− | if (/* условие 2 */) {
| + | |
− | /* если условие 2 истинно */
| + | |
− | } else {
| + | |
− | if (/* условие 3 */) {
| + | |
− | /* если условие 3 истинно */
| + | |
− | } else {
| + | |
− | ...
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | === Постфиксные операторы ===
| + | |
− | | + | |
− | Существует так же более лаконичная форма оператора <tt>'''if'''</tt>, удобная для записи коротких, однострочных условий. При этом, само условие записывается после выражения, которое оно должно проверить:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | /* выражение */ if /* условие */;
| + | |
− | </source>
| + | |
− | | + | |
− | При такой записи, окружать условие скобками не требуется. Проверяемое выражение должно быть единственным, то есть не содержать оператора точка с запятой (<tt>;</tt>). Такие условия занимают меньше места в программе и помогут сделать ваш код более чистым:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | var even_sum = 0;
| + | |
− | for (var i = 1; i < 100; i++) | + | |
− | even_sum += i if i % 2 == 0; //сумма всех четных чисел
| + | |
− | </source>
| + | |
− | | + | |
− | Для проверки "невыполнения" условия есть специальная форма постфиксного оператора — <tt>'''unless'''</tt>. Выражение при таком операторе будет выполняться только если условие ложно. Таким образом, смысл оператора прямо противоположен оператору <tt>'''if'''</tt>. Конечно, эти два оператора взаимозаменяемы. Конструкция <tt>do_smth '''if''' x;</tt> делает то же самое что <tt>do_smth '''unless''' !x;</tt>.
| + | |
− | | + | |
− | Перепишем предыдущий код с использованием оператора <tt>'''unless'''</tt>:
| + | |
− | | + | |
− | <source lang="kpp">
| + | |
− | var even_sum = 0;
| + | |
− | for (var i = 1; i < 100; i++)
| + | |
− | even_sum += i unless i % 2 != 0; //сумма всех четных чисел
| + | |
− | </source>
| + | |
− | | + | |
− | If my problem was a Death Star, this article is a pthoon torpedo.
| + | |
− | | + | |
− | FVPIQh <a href="http://qgxpytrzaaps.com/">qgxpytrzaaps</a>
| + | |
A few years ago I'd have to pay soomene for this information.