05-conditions.tex changed

This commit is contained in:
Maria_Grebenyuk 2022-10-23 15:27:47 +02:00
parent 5e85e3ab4b
commit 1792b1c2a6
1 changed files with 21 additions and 21 deletions

View File

@ -2,7 +2,7 @@
\subsection{Условный оператор}
\paragraph{\code{if()}} пожалуй, самый часто используемый в любом языке программирования, в том числе и в языке С оператор. Оператор \code{if()} позволяет программе принять решение о выполнении или невыполнении того или иного действия в зависимости от текущего состояния. В случае, если условие в круглых скобках выполнится, выполнится и последующий код, который чаще всего пишется в фигурных скобках. Если условие в круглых скобках не выполнится, то все операторы внутри идущих следом фигурных скобок будут проигнорированы.
Например, зададим пользователю вопрос, хочет ли он, чтобы его поприветствовали, для этого опишем переменную \code{char answer}, которая будет хранить ответ пользователя в виде символа и спросим у пользователя в терминале, хочет ли он, чтобы мы его поприветствовали, выведем на экран строку с приглашением. Далее при помощи уже знакомой нам функции \code{scanf();} считаем ответ пользователя в переменную, и, в зависимости от пользовательского ввода, программа либо поприветствует пользователя, либо нет, это решение будет принято с помощью оператора \code{if()}.
Например, зададим пользователю вопрос, хочет ли он, чтобы его поприветствовали. Для этого опишем переменную \code{char answer}, которая будет хранить ответ пользователя в виде символа, и спросим у пользователя в терминале, хочет ли он, чтобы мы его поприветствовали, выведем на экран строку с приглашением. Далее, при помощи уже знакомой нам функции \code{scanf();} считаем ответ пользователя в переменную, и, в зависимости от пользовательского ввода, программа либо поприветствует пользователя, либо нет, это решение будет принято с помощью оператора \code{if()}.
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -15,7 +15,7 @@
}
\end{lstlisting}
\end{figure}
\paragraph{\code{else}} Зачастую складываются ситуации, когда нужно выполнить разные наборы действий, в зависимости от результата проверки условия. Для таких случаев используется дополнение к оператору \code{if()} - оператор \code{else}, в котором описывается последовательность действий выполняемая в случае если условие в круглых скобках дало ложный результат. Код немного изменится, не будем приводить повторяющиеся части, взаимодействия с пользователем, сконцентрируемся на условном операторе:
\paragraph{\code{else}} Зачастую складываются ситуации, когда нужно выполнить разные наборы действий, в зависимости от результата проверки условия. Для таких случаев используется дополнение к оператору \code{if()} - оператор \code{else}, в котором описывается последовательность действий, выполняемая в случае, если условие в круглых скобках дало ложный результат. Код немного изменится, не будем приводить повторяющиеся части взаимодействия с пользователем, сконцентрируемся на условном операторе:
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -26,9 +26,9 @@
}
\end{lstlisting}
\end{figure}
Как вы видите, в зависимости от того что ввел пользователь мы реализуем ту или иную ветку оператора \code{if}-\code{else}. Конструкция \code{if}-\code{else} является единым оператором выбора, то есть выполнив код в фигурных скобках после \code{if} программа не станет выполнять код в \code{else}, и наоборот.
Как вы видите, в зависимости от того, что ввел пользователь, мы реализуем ту или иную ветку оператора \code{if}-\code{else}. Конструкция \code{if}-\code{else} является единым оператором выбора, то есть, выполнив код в фигурных скобках после \code{if}, программа не станет выполнять код в \code{else}, и наоборот.
\paragraph{\code{else if()}} Множественный выбор при помощи оператора \code{if} можно осуществить используя конструкцию \code{if}-\code{else if}-\code{else}. Данное усложнение также будет являться единым оператором выбора. Добавим в нашу конструкцию еще одно условие и опишем поведение для ответа <<да>> и ответа <<нет>>. В этом примере оператором \code{else} будет непонимание программы того что ввел пользователь. Выведем в консоль надпись <<Я не могу понять Ваш ввод>>.
\paragraph{\code{else if()}} Множественный выбор при помощи оператора \code{if} можно осуществить используя конструкцию \code{if}-\code{else if}-\code{else}. Данное усложнение также будет являться единым оператором выбора. Добавим в нашу конструкцию еще одно условие и опишем поведение для ответа <<да>> и ответа <<нет>>. В этом примере оператором \code{else} будет непонимание программы того, что ввел пользователь. Выведем в консоль надпись <<Я не могу понять Ваш ввод>>.
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -41,7 +41,7 @@
}
\end{lstlisting}
\end{figure}
Операторов \code{else if} в одном операторе выбора может быть сколько угодно, в отличие от оператора \code{if} и оператора \code{else} которых не может быть больше одного.
Операторов \code{else if} в одном операторе выбора может быть сколько угодно, в отличие от оператора \code{if} и оператора \code{else}, которых не может быть больше одного.
\begin{figure}[h!]
\begin{verbatim}
@ -57,7 +57,7 @@ I can't understand your input
$
\end{verbatim}
\end{figure}
\paragraph{Тернарный оператор.} Для короткой или внутристрочной записи условного оператора, а также для присваивания переменных по условию можно использовать \textbf{тернарный оператор}, также называемый оператором условного перехода и записываемый с помощью следующего синтаксиса: \code{(условие) ? истина : ложь}. Например, создадим три целочисленные переменные \code{а}, \code{b}, \code{c} и зададим двум из них какие-нибудь начальные значения, допустим \code{а = 10} и \code{b = 15}. Поставим себе задачу: присвоить переменной \code{c} наименьшее из значений \code{а} или \code{b}. Если мы будем использовать только что изученный нами оператор \code{if}-\code{else} у нас должен получиться такой код:
\paragraph{Тернарный оператор.} Для короткой или внутристрочной записи условного оператора, а также для присваивания переменных по условию можно использовать \textbf{тернарный оператор}, также называемый оператором условного перехода и записываемый с помощью следующего синтаксиса: \code{(условие) ? истина : ложь}. Например, создадим три целочисленные переменные \code{а}, \code{b}, \code{c} и зададим двум из них какие-нибудь начальные значения, допустим \code{а = 10} и \code{b = 15}. Поставим себе задачу: присвоить переменной \code{c} наименьшее из значений \code{а} и \code{b}. Если мы будем использовать только что изученный нами оператор \code{if}-\code{else}, у нас должен получиться такой код:
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -80,12 +80,12 @@ $
int c = (a > b) ? b : a;
\end{lstlisting}
\end{figure}
которая будет обозначать, что в случае если \code{a > b}, в переменную \code{c} запишется значение {b}, и наоборот если \code{b > a}, то в переменную \code{c} запишется значение \code{а}. Также тернарный оператор можно использовать для удобного форматированного вывода, например опишем функцию \code{printf();} которая будет печатать нам строку, и в зависимости от условия, это будет \code{"true"} либо \code{"false"}:
которая будет обозначать, что в случае если \code{a > b}, в переменную \code{c} запишется значение {b}, и наоборот, если \code{b > a}, то в переменную \code{c} запишется значение \code{а}. Также тернарный оператор можно использовать для удобного форматированного вывода, например опишем функцию \code{printf();}, которая будет печатать нам строку, и в зависимости от условия, это будет \code{"true"} либо \code{"false"}:
\begin{lstlisting}[language=C,style=CCodeStyle]
printf("%s", (1 > 0) ? "true" : "false");
\end{lstlisting}
Проверим как это работает, и в результате видим true, потому что единица действительно больше нуля.
Проверим, как это работает, и в результате видим true, потому что единица действительно больше нуля.
\begin{figure}[h!]
\begin{verbatim}
@ -95,7 +95,7 @@ $
\end{verbatim}
\end{figure}
\paragraph{Вложенные условия и сокращения}
Внутри фигурных скобок конструкций \code{if()} находится код программы, поэтому там могут находиться и другие условные операторы. Условия, расположенные таким образом называются вложенными. Никаких ограничений на использование вложенных условий в языке С нет. В примере ниже показано, что условия всегда выполняются (единица в круглых скобках будет означать, что условие всегда истинно), а комментариями с многоточием показано, где может располагаться код программы.
Внутри фигурных скобок конструкций \code{if()} находится код программы, поэтому там могут находиться и другие условные операторы. Условия, расположенные таким образом, называются вложенными. Никаких ограничений на использование вложенных условий в языке С нет. В примере ниже показано, что условия всегда выполняются (единица в круглых скобках будет означать, что условие всегда истинно), а комментариями с многоточием показано, где может располагаться код программы.
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -128,16 +128,16 @@ $
// single operator
\end{lstlisting}
\end{figure}
При использовании такой записи можно легко допустить ошибку: забыть о необходимости объединения кода фигурными скобками, и предполагать, что несколько операторов могут выполниться по условию без фигурных скобок.
При использовании такой записи можно легко допустить ошибку: забыть о необходимости объединения кода фигурными скобками и предполагать, что несколько операторов могут выполниться по условию без фигурных скобок.
\frm{Часто это заблуждение приводит к трудноуловимым ошибкам в коде, когда программа компилируется, запускается, но работает не так, как следует.}
\subsection{Операции сравнения}
\paragraph{Арифметическое сравнение} это знакомые и привычные нам со школы операторы <<больше>> (\code{>}), <<меньше>> (\code{<}), <<больше или равно>> (\code{>=}), <<меньше или равно>> (\code{<=}), а также в языке С присутствуют в виде отдельных операторов <<проверка на равенство>>, которая записывается в виде двух знаков равенства (\code{==}), и <<проверка на неравенство>>, которая записывается в виде восклицательного знака и символа равенства (\code{!=}). Возвращают истину, когда выполняются соответствующие названиям условия и ложь, когда условия не выполняются, что очевидно. Единственное исключение, которое было оговорено ранее (\hyperref[text:floats]{\ref{text:floats}}), сравнение разнотипных нецелочисленных значений должно осуществляться через сравнение допустимой дельты этих значений, например:
\paragraph{Арифметическое сравнение} это знакомые и привычные нам со школы операторы <<больше>> (\code{>}), <<меньше>> (\code{<}), <<больше или равно>> (\code{>=}), <<меньше или равно>> (\code{<=}), а также в языке С присутствуют в виде отдельных операторов <<проверка на равенство>>, которая записывается в виде двух знаков равенства (\code{==}), и <<проверка на неравенство>>, которая записывается в виде восклицательного знака и символа равенства (\code{!=}). Возвращают истину, когда выполняются соответствующие названиям условия, и ложь, когда условия не выполняются, что очевидно. Единственное исключение, которое было оговорено ранее (\hyperref[text:floats]{\ref{text:floats}}), сравнение разнотипных нецелочисленных значений должно осуществляться через сравнение допустимой дельты этих значений, например:
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
float f = 0.5f;
double d = 0.5;
fouble diff = (f > d) ? f - d : d - f;
double diff = (f > d) ? f - d : d - f;
if (diff < 0.00001) {
// useful code here
}
@ -151,7 +151,7 @@ $
\end{lstlisting}
Некоторые компиляторы выдают ошибку на этапе компиляции, некоторые компилируют такой код, но программа не сможет выполниться и выдаст ошибку \textbf{Segmentation fault}, то есть ошибку доступа к памяти (попытка обратиться к недоступной памяти или попытка обратиться к памяти неподобающим образом). В этой конкретной ситуации, мы попытаемся интерпретировать как строку часть памяти, которая находится по адресу 1, что находится далеко за пределами доступа программы. Это поведение (ошибка компиляции или ошибка времени выполнения) зависит от большого количества факторов, таких как тип операционной системы, тип и версия компилятора, версия используемого стандарта языка.
Отдельного внимания заслуживает применение оператора поразрядного (арифметического) \code{ИСКЛЮЧАЮЩЕГО ИЛИ} в качестве логического. В случае такого применения оператор \code{ИСКЛЮЧАЮЩЕГО ИЛИ}, фактически, дублирует сравнение на неравенство, это легко объяснить, проведя анализ происходящего с числами при таком сравнении:
Отдельного внимания заслуживает применение оператора поразрядного (арифметического) \code{ИСКЛЮЧАЮЩЕГО ИЛИ} в качестве логического. В случае такого применения оператор \code{ИСКЛЮЧАЮЩЕГО ИЛИ} фактически дублирует сравнение на неравенство, это легко объяснить, проведя анализ происходящего с числами при таком сравнении:
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -163,9 +163,9 @@ $
}
\end{lstlisting}
\end{figure}
Данный код внутри фигурных скобок оператора \code{if()} никогда не выполнится, поскольку в С оператор сравнения работает с числами, интерпретируя ноль как ложь, а любое ненулевое значение как истину, мы наблюдаем, что побитовое \code{ИСКЛЮЧАЮЩЕЕ ИЛИ} - это тоже самое, что проверка на неравенство.
Данный код внутри фигурных скобок оператора \code{if()} никогда не выполнится, поскольку в С оператор сравнения работает с числами, интерпретируя ноль как ложь, а любое ненулевое значение - как истину, мы наблюдаем, что побитовое \code{ИСКЛЮЧАЮЩЕЕ ИЛИ} - это тоже самое, что проверка на неравенство.
\begin{itemize}
\item оператор \code{И (\&\&)} возвращает истину только когда оба операнда истинны;
\item оператор \code{И (\&\&)} возвращает истину, только когда оба операнда истинны;
\begin{tabular}{|c|c|c|}
\hline
@ -180,7 +180,7 @@ $
1 & 1 & 1 \\
\hline
\end{tabular}
\item оператор \code{ИЛИ (||)} возвращает истину когда хотя бы один из операндов истинный;
\item оператор \code{ИЛИ (||)} возвращает истину, когда хотя бы один из операндов истинный;
\begin{tabular}{|c|c|c|}
\hline
@ -195,7 +195,7 @@ $
1 & 1 & 1 \\
\hline
\end{tabular}
\item оператор \code{НЕ (!)} возвращает истину когда операнд ложный;
\item оператор \code{НЕ (!)} возвращает истину, когда операнд ложный;
\begin{tabular}{|c|c|}
\hline
@ -208,7 +208,7 @@ $
\end{tabular}
\end{itemize}
Используя логические операторы в программе мы можем написать логику практически любой сложности. В языке С нет ограничений на использование сложных условий. Сложные условия это такие, где в круглых скобках выполняется более одного сравнения. Сравнения производятся в порядке заранее оговоренного приоритета. В списке ниже указаны операторы в порядке уменьшения их приоритета:
Используя логические операторы в программе, мы можем написать логику практически любой сложности. В языке С нет ограничений на использование сложных условий. Сложные условия это такие, где в круглых скобках выполняется более одного сравнения. Сравнения производятся в порядке заранее оговорённого приоритета. В списке ниже указаны операторы в порядке уменьшения их приоритета:
\begin{enumerate}
\item $!$
\item $<, <=, >, >=$
@ -216,7 +216,7 @@ $
\item $\&\&$
\item $||$
\end{enumerate}
Приведём короткий пример: дана некоторая целочисленная переменная и нужно выяснить, не выходит ли эта переменная за рамки заданных значений, например от нуля до десяти. Условие можно будет скомбинировать так: \code{x >= 0 \&\& x <= 10}. В случае его истинности - выдадим сообщение о том, что \code{х} подходит.
Приведём короткий пример: дана некоторая целочисленная переменная, и нужно выяснить, не выходит ли эта переменная за рамки заданных значений, например от нуля до десяти. Условие можно будет скомбинировать так: \code{x >= 0 \&\& x <= 10}. В случае его истинности - выдадим сообщение о том, что \code{х} подходит.
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]
@ -235,9 +235,9 @@ X Fits!
$
\end{verbatim}
\end{figure}
Самый не приоритетный оператор тернарный, внимательный читатель мог заметить, что он даже не вошёл в список выше, это сделано, поскольку использование тернарного оператора внутри условий нежелательно. Тернарный оператор внутри условий резко снижает читаемость кода и усложняет его интерпретацию. Если Вы сомневаетесь в приоритете сравнений или Вам необходимо описать какое-то очень сложное условие, всегда можно воспользоваться простыми математическими круглыми скобками, задав приоритет операций явно. В таком случае в первую очередь будут выполнены операции в скобках.
Самый не приоритетный оператор - тернарный, внимательный читатель мог заметить, что он даже не вошёл в список выше, это сделано, поскольку использование тернарного оператора внутри условий нежелательно. Тернарный оператор внутри условий резко снижает читаемость кода и усложняет его интерпретацию. Если Вы сомневаетесь в приоритете сравнений или Вам необходимо описать какое-то очень сложное условие, всегда можно воспользоваться простыми математическими круглыми скобками, задав приоритет операций явно. В таком случае в первую очередь будут выполнены операции в скобках.
\subsection{Блоки кода и область видимости}
Говоря об операторах языка С и управляющих конструкциях нельзя не сказать о <<блоках кода>> и <<областях видимости>>. Как видно, условные операторы содержат записи в фигурных скобках. В такие же скобки заключён код функции \code{main}. Эти скобки называются <<операторными>>, а то что в них содержится, называется <<блоком кода>> или <<телом>> оператора или функции. Все переменные, которые инициализируются внутри блока кода, существуют и <<видны>> только внутри кодового блока. Поэтому пространство между операторными скобками также называют <<областью видимости>>.
Говоря об операторах языка С и управляющих конструкциях, нельзя не сказать о <<блоках кода>> и <<областях видимости>>. Как видно, условные операторы содержат записи в фигурных скобках. В такие же скобки заключён код функции \code{main}. Эти скобки называются <<операторными>>, а то, что в них содержится, называется <<блоком кода>> или <<телом>> оператора или функции. Все переменные, которые инициализируются внутри блока кода, существуют и <<видны>> только внутри кодового блока. Поэтому пространство между операторными скобками также называют <<областью видимости>>.
\begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle]