diff --git a/build/main.pdf b/build/main.pdf index d9bd3a1..ca5803d 100644 Binary files a/build/main.pdf and b/build/main.pdf differ diff --git a/sections/06-cycles.tex b/sections/06-cycles.tex index bd6407e..52095f9 100644 --- a/sections/06-cycles.tex +++ b/sections/06-cycles.tex @@ -143,24 +143,7 @@ for (i = 0; i < significative; i++) { printf("%d powered by %d is %d \n", base, significative, result); \end{lstlisting} Конечно, мы можем спросить у пользователя какое число, и в какую степень он хочет возвести, для этого применим уже привычные нам конструкции. Так, весь код программы будет иметь следующий вид: -\begin{lstlisting}[language=C,style=CCodeStyle] -#include - -int main(int argc, char *argv[]) { - int i; - int base; - int significative; - int result = 1; - printf("Enter base: "); - scanf("%d", &base); - printf("Enter significative: "); - scanf("%d", &significative); - for (i = 0; i < significative; i++) { - result *= base; - } - printf("%d powered by %d is %d \n", base, significative, result); -} -\end{lstlisting} +\lstinputlisting[language=C,style=CCodeStyle]{../sources/power.c} Запустим нашу программу, введем для базы значение два, для показателя десять. Убедимся, что наша программа работает корректно, $2^{10}=1024$. \begin{verbatim} $ ./program @@ -201,29 +184,7 @@ if (dividers == 3) break; \end{lstlisting} Если количество целочисленных делителей не изменилось, то мы прекратим текущую итерацию цикла при помощи ключевого слова \code{continue}. Как мы знаем, оператор \code{continue} передаст управление в логическую конструкцию цикла, заставив программу проигнорировать все дальнейшие инструкции в рамках текущей итерации. Если количество целочисленных делителей достигнет трёх, что будет означать нецелесообразность дальнейших вычислений, мы разорвем цикл при помощи ключевого слова \code{break}. И полный получившийся код приложения будет такой: -\begin{lstlisting}[language=C,style=CCodeStyle] -#include - -int main(int argc, char *argv[]) { - int number; - int dividers = 0, i = 1; - printf("Enter number: "); - scanf("%d", &number); - while (i <= number) { - if (number++ % i == 0) { - dividers++; - } else { - continue; - } - if (dividers == 3) - break; - } - printf("Number %d is%s prime", - number, - (dividers == 2) ? "" : " not" - ); -} -\end{lstlisting} +\lstinputlisting[language=C,style=CCodeStyle]{../sources/prime.c} Естественно, повторимся, этот код можно оптимизировать по множеству направлений, как минимум, сократив как количество проверок, так и границы проверок (нет смысла проверять числа больше, чем $\sqrt{number}$). Дополнительно можно не проверять чётные числа, например. \begin{verbatim} $ ./program @@ -291,50 +252,7 @@ default: Оператор \code{switch()\{\}} последовательно проверит входящую переменную на соответствие описанным в кейсах значениях. В случае, если значение совпадёт, будет выполнен блок кода до оператора \code{break;}, если же значение переменной не совпадёт ни с одним из описанный в кейсах, выполнится блок по умолчанию \code{default}. \frm{Важно помнить, что в случае отсутствия внутри \code{case} оператора \code{break;}, программа будет выполнять последующие кейсы, пока не найдёт \code{break;} или пока не закончится конструкция \code{switch()\{\}}, то есть пока не встретится её закрывающая фигурная скобка.} В кейсах мы опишем присваивание результата в переменную \code{result}, а после выхода из \code{switch()\{\}} - вывод результата в консоль. Кейсом по умолчанию будет вывод пользователю сообщения о невозможности распознать оператор. Так получается, что даже если мы ввели неизвестный оператор, программа попытается вывести в консоль результат, что неприемлемо. Поэтому кейс по умолчанию должен содержать также и оператор \code{return 1;} вынуждающий программу экстренно завершиться с кодом ошибки \code{1}. Получится такой код: -\begin{lstlisting}[language=C,style=CCodeStyle] -#include - -int main (int argc, char *argv[]) { - float first; - float second; - float result; - int operator; - - printf("Enter first operand: "); - scanf("%f", &first); - printf("/nEnter 1 for (+), 2 for (-), 3 for (*), 4 for (/): "); - scanf("%d", &operator); - if (operator == 4) { - do { - printf("/nEnter second operand: "); - scanf("%f", &second); - } while (second == 0); - } else { - printf("/nEnter second operand: "); - scanf("%f", &second); - } - switch (operator) { - case 1: - result = first + second; - break; - case 2: - result = first - second; - break; - case 3: - result = first * second; - break; - case 4: - result = first / second; - break; - default: - printf("Unknown operator\n"); - return 1; - } - - printf("Result is: %f \n", result); - return 0; -} -\end{lstlisting} +\lstinputlisting[language=C,style=CCodeStyle]{../sources/calculator.c} Запустив описанный нами калькулятор, убедимся что все работает. Сымитируем нерадивого пользователя и несколько раз попробуем ввести при использовании четвёртого оператора цифру ноль, программа естественно не даст нам этого сделать. \begin{verbatim} $ ./program diff --git a/sources/calculator.c b/sources/calculator.c new file mode 100644 index 0000000..5c253cb --- /dev/null +++ b/sources/calculator.c @@ -0,0 +1,42 @@ +#include + +int main (int argc, char *argv[]) { + float first; + float second; + float result; + int operator; + + printf("Enter first operand: "); + scanf("%f", &first); + printf("/nEnter 1 for (+), 2 for (-), 3 for (*), 4 for (/): "); + scanf("%d", &operator); + if (operator == 4) { + do { + printf("/nEnter second operand: "); + scanf("%f", &second); + } while (second == 0); + } else { + printf("/nEnter second operand: "); + scanf("%f", &second); + } + switch (operator) { + case 1: + result = first + second; + break; + case 2: + result = first - second; + break; + case 3: + result = first * second; + break; + case 4: + result = first / second; + break; + default: + printf("Unknown operator\n"); + return 1; + } + + printf("Result is: %f \n", result); + return 0; +} diff --git a/sources/power.c b/sources/power.c new file mode 100644 index 0000000..5cc4b13 --- /dev/null +++ b/sources/power.c @@ -0,0 +1,16 @@ +#include + +int main(int argc, char *argv[]) { + int i; + int base; + int significative; + int result = 1; + printf("Enter base: "); + scanf("%d", &base); + printf("Enter significative: "); + scanf("%d", &significative); + for (i = 0; i < significative; i++) { + result *= base; + } + printf("%d powered by %d is %d \n", base, significative, result); +} diff --git a/sources/prime.c b/sources/prime.c new file mode 100644 index 0000000..97f420f --- /dev/null +++ b/sources/prime.c @@ -0,0 +1,21 @@ +#include + +int main(int argc, char *argv[]) { + int number; + int dividers = 0, i = 1; + printf("Enter number: "); + scanf("%d", &number); + while (i <= number) { + if (number++ % i == 0) { + dividers++; + } else { + continue; + } + if (dividers == 3) + break; + } + printf("Number %d is%s prime", + number, + (dividers == 2) ? "" : " not" + ); +}