Merge pull request 'buzzkill' (#1) from lornaria/basic-c:buzzkill into master

Reviewed-on: #1
This commit is contained in:
ivan-igorevich 2022-11-02 10:28:13 +03:00
commit 75f60c00c5
2 changed files with 27 additions and 27 deletions

View File

@ -1,7 +1,7 @@
\section{Базовый ввод-вывод} \section{Базовый ввод-вывод}
\subsection{Форматированный вывод} \subsection{Форматированный вывод}
Общение с пользователем на чистом С происходит через консоль. Для того, чтобы выводить какую-либо информацию для чтения пользователем - используется функция \code{printf();} предназначенная для форматированного вывода некоторого текста в консоль. Функция описана в заголовке \code{stdio.h}, поэтому мы и включили данный заголовок в нашу программу. Какого рода форматирование применяется при выводе строк в консоль? Существуют два основных инструмента придания выводу необходимого вида: экранированные последовательности (escape sequences) и заполнители (placeholders). Общение с пользователем на чистом С происходит через консоль. Для того, чтобы выводить какую-либо информацию для чтения пользователем - используется функция \code{printf();} предназначенная для форматированного вывода некоторого текста в консоль. Функция описана в заголовке \code{stdio.h}, поэтому мы и включили данный заголовок в нашу программу. Какого рода форматирование применяется при выводе строк в консоль? Существуют два основных инструмента придания выводу необходимого вида: экранированные последовательности (escape sequences) и заполнители (placeholders).
\paragraph{Экранированная последовательность} это буква или символ, написанные после знака обратного слэша (\code{\char`\\}), которые при выполнении программы будут на что-то заменены. Самые часто используемые это: \paragraph{Экранированная последовательность} - это буква или символ, написанные после знака обратного слэша (\code{\char`\\}), которые при выполнении программы будут на что-то заменены. Самые часто используемые это:
\begin{itemize} \begin{itemize}
\item \code{\char`\\'} - одинарная кавычка; \item \code{\char`\\'} - одинарная кавычка;
\item \code{\char`\\"} - двойная кавычка; \item \code{\char`\\"} - двойная кавычка;
@ -18,7 +18,7 @@
\item \code{\char`\\xnn} - произвольное шестнадцатеричное значение; \item \code{\char`\\xnn} - произвольное шестнадцатеричное значение;
\item \code{\char`\\unnnn} - произвольное Юникод-значение. \item \code{\char`\\unnnn} - произвольное Юникод-значение.
\end{itemize} \end{itemize}
Чтобы убедится что это правильно работает выведем еще одну строку (в дополнение к коду со страницы \hyperref[code:firstprogram]{\pageref{code:firstprogram}}) с надписью <<Это новая строка>> на следующую строку нашей консоли. Также добавим к ещё одной строке символ табуляции чтобы увидеть как он работает. И сразу рассмотрим экранированную последовательность \code{\char`\\\char`\\} она делает ни что иное как добавляет символ обратного слэша в наш текст. Аналогичным образом работают и другие символьные экранирования. Это нужно, чтобы компилятор мог отличить, например, символ двойных кавычек в строке, написанной программистом, от символа двойных кавычек, завершающего строку в коде программы. Обратите внимание что не поставив в конец строки последовательность \code{\char`\\n} мы заставим компилятор постоянно писать текст на одной строке, не переходя на новую. И наконец \code{\char`\\0} сообщает компилятору что строка закончилась. Даже если у нас есть еще какие-то символы до закрывающих кавычек компилятор их просто проигнорирует. Добавим в код программы ещё пару строк, таким образом тело функции \code{main} должно принять следующий вид: Чтобы убедиться, что это правильно работает, выведем еще одну строку (в дополнение к коду со страницы \hyperref[code:firstprogram]{\pageref{code:firstprogram}}) с надписью <<Это новая строка>> на следующую строку нашей консоли. Также добавим к ещё одной строке символ табуляции чтобы увидеть как он работает. И сразу рассмотрим экранированную последовательность \code{\char`\\\char`\\} она делает не что иное, как добавляет символ обратного слэша в наш текст. Аналогичным образом работают и другие символьные экранирования. Это нужно, чтобы компилятор мог отличить, например, символ двойных кавычек в строке, написанной программистом, от символа двойных кавычек, завершающего строку в коде программы. Обратите внимание, что, не поставив в конец строки последовательность \code{\char`\\n}, мы заставим компилятор постоянно писать текст на одной строке, не переходя на новую. И наконец, \code{\char`\\0} сообщает компилятору, что строка закончилась. Даже если у нас есть еще какие-то символы до закрывающих кавычек, компилятор их просто проигнорирует. Добавим в код программы ещё пару строк, таким образом тело функции \code{main} должно принять следующий вид:
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle] \begin{lstlisting}[language=C,style=CCodeStyle]
@ -29,7 +29,7 @@
printf("This is a terminant \0 it ends a string"); printf("This is a terminant \0 it ends a string");
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
Запустив программу мы можем убедиться, что всё работает так, как мы описали в тексте: сначала идёт приветствие миру, на новой строке сообщение о том, что это новая строка, далее на той же строке (ведь мы не переходили на новую) демонстрация пробела и символа табуляции. На последних двух строках происходит демонстрация обратного слэша и терминанта, видно, что остаток строки не был выведен на экран. Запустив программу, мы можем убедиться, что всё работает так, как мы описали в тексте: сначала идёт приветствие миру, на новой строке сообщение о том, что это новая строка, далее на той же строке (ведь мы не переходили на новую) демонстрация пробела и символа табуляции. На последних двух строках происходит демонстрация обратного слэша и терминанта, видно, что остаток строки не был выведен на экран.
\begin{figure}[h!] \begin{figure}[h!]
\begin{verbatim} \begin{verbatim}
@ -41,7 +41,7 @@ This is terminant
$ $
\end{verbatim} \end{verbatim}
\end{figure} \end{figure}
\paragraph{Заполнитель} это также специальная последовательность, но она говорит компилятору, что на место этой последовательности необходимо вставить некий аргумент, который будет передан после строки, через запятую, при вызове данной функции \code{printf();}. Заполнитель начинается со знака процента и обозначает тип вставляемой переменной. \paragraph{Заполнитель} - это также специальная последовательность, но она говорит компилятору, что на место этой последовательности необходимо вставить некий аргумент, который будет передан после строки, через запятую, при вызове данной функции \code{printf();}. Заполнитель начинается со знака процента и обозначает тип вставляемой переменной.
\begin{itemize} \begin{itemize}
\item \code{\%\%} - символ процента; \item \code{\%\%} - символ процента;
\item \code{\%i (\%d)} - целые числа (integer, decimal); \item \code{\%i (\%d)} - целые числа (integer, decimal);
@ -65,7 +65,7 @@ $
printf("Placeholders are \"%5d%%\" of formatting\n", a); printf("Placeholders are \"%5d%%\" of formatting\n", a);
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
Так первый оператор выведет просто число. Второй это же число, но оставив для его отображения пять пробельных символов (два окажутся заняты разрядами числа 50, и ещё три останутся свободными, слева от числа). Третий оператор форматированного вывода впишет число в пять отображаемых символов, но заполнит пустоту нулями (запись с лидирующими нулями, leading zeroes). Четвёртый осуществит вывод числа с плавающей точкой, ограничив дробную часть двумя отображаемыми символами, при этом важно, что не произойдёт математического округления, символы просто не отобразятся, такое отображение часто используется для демонстрации денежных значений в долларах и центах, рублях и копейках, и пр. Последний же оператор выведет на экран надпись, информирующую о том, что заполнители - это 50\% форматирования: Так первый оператор выведет просто число. Второй это же число, но оставив для его отображения пять пробельных символов (два окажутся заняты разрядами числа 50, и ещё три останутся свободными слева от числа). Третий оператор форматированного вывода впишет число в пять отображаемых символов, но заполнит пустоту нулями (запись с лидирующими нулями, leading zeroes). Четвёртый осуществит вывод числа с плавающей точкой, ограничив дробную часть двумя отображаемыми символами, при этом важно, что не произойдёт математического округления, символы просто не отобразятся, такое отображение часто используется для демонстрации денежных значений в долларах и центах, рублях и копейках, и пр. Последний же оператор выведет на экран надпись, информирующую о том, что заполнители - это 50\% форматирования:
\begin{figure}[h!] \begin{figure}[h!]
\begin{verbatim} \begin{verbatim}
@ -80,7 +80,7 @@ $
\end{figure} \end{figure}
Для заполнителей \code{\%d}, \code{\%i}, \code{\%f} часто используются дополнительные параметры, такие как количество знаков после запятой, например, \code{\%.2f} или минимальное количество знаков для отображения целого числа \code{\%5d}. Также в пользу оператора форматированного вывода говорит тот факт, что, например, в С++ стандартный вывод в консоль осуществляется с помощью команды \code{std::cout}, которая не поддерживала форматирование строк вплоть до принятия стандарта С++20. Для заполнителей \code{\%d}, \code{\%i}, \code{\%f} часто используются дополнительные параметры, такие как количество знаков после запятой, например, \code{\%.2f} или минимальное количество знаков для отображения целого числа \code{\%5d}. Также в пользу оператора форматированного вывода говорит тот факт, что, например, в С++ стандартный вывод в консоль осуществляется с помощью команды \code{std::cout}, которая не поддерживала форматирование строк вплоть до принятия стандарта С++20.
\subsection{Форматированный ввод} \subsection{Форматированный ввод}
Поговорив о выводе в консоль нельзя не сказать о пользовательском вводе данных. Один из способов пользовательского ввода данных в программу - это использование функции \code{scanf();}. Предложим пользователю ввести некоторое число: Поговорив о выводе в консоль, нельзя не сказать о пользовательском вводе данных. Один из способов пользовательского ввода данных в программу - это использование функции \code{scanf();}. Предложим пользователю ввести некоторое число:
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle] \begin{lstlisting}[language=C,style=CCodeStyle]

View File

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