Урок №7 Логические переменные и цикл while

Теория:

IЛогические переменные

Под логическими переменными подразумеваются переменные, которые могут иметь только два значения: правда и ложь. Данные переменные очень удобны и могут быть использованы в качестве индикаторов. Например, необходимо осуществить проверку числа на предмет принадлежности тому или иному множеству. После данной проверки программа кладёт в логическую переменную одно из двух значений: правда и ложь, в зависимости от того, пройдена или не пройдена проверка данного числа. Затем, исходя из значения данного индикатора, будет выполнены те или иные действия.
Логические переменные в С/С++
В языке программирования логические переменные - это переменные типа bool (от англ. boolean — логический), а значения, которые принимают данные переменные - это true (от англ. true — правда) и false (от англ. false — ложь).
Название bool было выбрано в честь знаменитого математика Джорджа Буля, который создал алгебру логики или булевскую алгебру
Использование в циклах
Логические переменные очень удобно использовать в циклах в качестве условия, так как при проверке на истинность того или иного условия, например, цикл if отправляет это условие в соответствующий оператор, а затем, в зависимости от того, true или false вернул оператор, условие считается истинным или ложным соответственно. Например, если условие в цикле if имеет вид a > b, цикл if отправляет две переменные a и b оператору >, который уже в зависимости от значений данных переменных возвращает true или false. И только потом компилятор либо выполняет команды в цикле if, либо нет. Работая с логическими переменными напрямую позволяет выполнять проверку условий в циклах гораздо быстрее, потому что циклу if не нужно вызывать никакого оператора.

IIЦикл while

В языке С/С++ есть также не менее популярный цикл while, суть которого заключается в выполнении команд из тела цикла, пока выполнено условие цикла. Рассмотрим следующий код:
int x = 10; // создаём целочисленную переменную х
while(x > 5){ // запускаем цикл while
    printf("x = %d\n", x); // выписываем значение переменной х
    x--; // уменьшаем значение переменной х на единицу
}
При его запуске программа выведет в консоли:
x = 10
x = 9
x = 8
x = 7
x = 6
То есть цикл будет выполнять команды из своего тела, пока переменная х больше числа 5. При этом в каждом проходе значение данной переменной уменьшается на единицу. Когда значение переменной становится равным 5, условие  x > 5 перестаёт быть истинным и цикл while завершает свою работу. Заметим, что если строгое неравенство в условии поменять на нестрогое, программа выведет в консоли:
x = 10
x = 9
x = 8
x = 7
x = 6
x = 5
Так как при значении переменной х = 5 условие x >= 5 всё ещё остаётся истинным, и цикл while завершает свою работу только тогда, когда значение х станет равным числу 4. Цикл while является аналогом цикла for. В некоторых задачах, он удобней, а в некоторых - нет. В предыдущих уроках мы рассмотрели довольно широкий класс задач, которые очень хорошо решаются при помощи цикла for.

IIIБесконечный цикл while

Заметим также, что в примерах выше условие цикла while рано или поздно становилось ложным, и цикл завершал свою работу. Если же написать такое условие, которое всегда будет истинно, то можно получить бесконечный цикл while, который будет выполняться до тех пор, пока у компьютера хватит ресурсов. Поэтому при работе с циклом while всегда необходимо проверять, что он не будет бесконечным. Но иногда специально нужно использовать именно бесконечный цикл whileТогда возникает потребность в команде для принудительного выхода из цикла и его завершения. Такая команда есть, и она абсолютна безвредна для программного кода. Это команда break;. Она принудительно завершает любой цикл (и цикл for в том числе), когда это необходимо по соображениям алгоритма. Рассмотрим следующий код:
int k = 0;
while(2 > 1){
    printf("%d) Do something...\n", k + 1);
    if (k >= 15){
        break;
    } else {
        k++;
    }
}
При его запуске программа выведет в консоли:
1) Do something...
2) Do something...
3) Do something...
4) Do something...
5) Do something...
6) Do something...
7) Do something...
8) Do something...
9) Do something...
10) Do something...
11) Do something...
12) Do something...
13) Do something...
14) Do something...
15) Do something...
16) Do something...
Не трудно заметить, что в этом случае ограничителем является не убывающее значение переменной, находящейся внутри условия цикла while, а возрастающее значение сторонней переменной. Цикл while является бесконечным, а его завершение происходит по команде break; после достижения значения переменной k числа 15. Так как изначально значение переменнойk было 0, то в консоль выписалось 16 строк (чисел от 0 до 15 — 16 штук). Бесконечный цикл while обычно создают при помощи логических переменных:
while (true){
    // делаем что-нибудь
}

IVПодсчёт суммы цифр числа

Подсчёт суммы цифр числа является популярной и распространённой задачей. А также данная задача явно демонстрирует преимущество цикла while над циклом for. Как мы уже знаем, чтобы вычислить последнюю цифру числа, нужно взять остаток при делении этого числа на 10. А чтобы получить вторую справа цифру числа, нужно сначала разделить данное число на 10 в целых числах, а затем снова взять остаток при делении на 10. Таким образом, мы получаем явный цикл, состоящий из команд взятия остатка при делении на 10 и делении на 10 в целых числах. Но загвоздкой и невозможностью применить цикл for является тот факт, что мы не можем жестко задать, сколько раз необходимо повторять вышеуказанные команды, так как числа могут быть совершенно различной размерности. Например, для трехзначных чисел необходимо выполнить данные команды 3 раза, а для шестизначных - 6 раз. Поэтому цикл for в данной задаче неприменим. А вот цикл while справится с подсчётом суммы цифр на ура. Заметим, что команды взятия остатка при делении на 10 и делении на 10 в целых числах необходимо выполнять до тех пор, пока число не станет нулём. И таким образом получается явная конструкция с использованием цикла while:
while (x > 0){ // пока переменная х больше нуля
    s += x % 10; // прибавляем к переменной s последнюю цифру числа х
    x /= 10; // делим число х на 10 в целых числах
}

Практика

1Задача №1.

Выписать все квадраты натуральных чисел, меньшие числа 100.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int x = 1; // создаём целочисленные переменные
    while (x * x <= 100){ // запускаем цикл while
        printf("%d^2 = %d\n", x, x * x); // выписываем квадрат
        x++; // увеличиваем число х на единицу
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
1^2 = 1
2^2 = 4
3^2 = 9
4^2 = 16
5^2 = 25
6^2 = 36
7^2 = 49
8^2 = 64
9^2 = 81
10^2 = 100

Process returned 0 (0x0)   execution time : 0.010 s
Press any key to continue.

2Задача №2.

Написать программу, возводящую и выписывающую числа, введённые пользователем, в квадрат до тех пор, пока пользователь вводит числа. Как только пользователь введёт какой-нибудь символ, программа должна завершиться, попрощавшись с пользователем.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int x = 0; // создаём целочисленные переменные
    while (true){ // запускаем бесконечный цикл while
        printf("Print the number: "); // приглашаем пользователя на ввод
        if (scanf("%d", &x) != 1){ // если число считано корректно
            printf("Goodbye!\n"); // прощаемся с пользователем
            return 0; // возвращаем 0 - успех
        }
        printf("%d^2 = %d\n", x, x * x); // выписываем квадрат пользовательского числа
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print the number: 12
12^2 = 144
Print the number: -3
-3^2 = 9
Print the number: 10
10^2 = 100
Print the number: -1
-1^2 = 1
Print the number: 4
4^2 = 16
Print the number: q
Goodbye!

Process returned 0 (0x0)   execution time : 15.076 s
Press any key to continue.

3Задача №3,

Написать программу, выписывающую, есть ли в числе, введённом пользователем, цифра 3, пока пользователь вводит числа. Как только пользователь введёт какой-нибудь символ, программа должна завершиться, попрощавшись с пользователем.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h
#include <math.h> // подключаем библиотеку math.h

int main(){ // создаём главную функцию
    int x = 0; // создаём целочисленные переменные
    bool x_contains_3 = false; // создаём индикатор того, что х содержит цифру 3
    while (true){ // запускаем бесконечный цикл while
        printf("Print the number: "); // приглашаем пользователя на ввод
        if (scanf("%d", &x) != 1){ // если число считано корректно
            printf("Goodbye!\n"); // прощаемся с пользователем
            return 0; // возвращаем 0 - успех
        }
        x_contains_3 = false; // пока что мы не нашли цифру 3, поэтому ставим индикатор в значение false
        while (abs(x) > 0){ // пока переменная х больше нуля
            if (x % 10 == 3 || x % 10 == -3){ // проверяем, что последняя цифра числа х это 3 или -3
                x_contains_3 = true; // если нашли цифру 3, ставим индикатор в значение true
                break; // выходим из цикла while в целях экономии времени, так как цифра 3 уже найдена
            }
            x /= 10; // делим число х на 10 в целых числах
        }
        if (x_contains_3){ // проверяем значение индикатора
            printf("Your number contains 3\n"); // выводим, что число пользователя содержит цифру 3
        } else {
            printf("Your number DON'T contains 3\n"); // выводим, что число пользователя не содержит цифру 3
        }
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print the number: -345
Your number contains 3
Print the number: -278
Your number DON'T contains 3
Print the number: 345
Your number contains 3
Print the number: 278
Your number DON'T contains 3
Print the number: -3333333
Your number contains 3
Print the number: 90
Your number DON'T contains 3
Print the number: q
Goodbye!

Process returned 0 (0x0)   execution time : 19.886 s
Press any key to continue.
Чтобы программа работала и для отрицательных числах, необходимо проверять, не равна ли последняя цифра на очередном этапе цикла while 3 или -3. Также необходимо взять модуль abs() из библиотеки math.h в условии цикла while

Домашнее задание:

1Задача №1.

В последовательности первое число - единица, а каждое следующее больше предыдущего на свой порядковый номер. То есть, начало последовательности имеет вид:

1, 3, 6, 10, 15, 21, 28, \cdots Здесь число 3 = 1 + 2, так как 3 стоит на 2-м месте, а перед ним стоит число 1. Число 21 = 15 + 6, так как число 21 стоит на 6-м месте, а перед ним стоит число 15. Напишите программу, выписывающую все элементы последовательности, меньшие 100.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int a_now = 1, a_before = 1, i = 2; // создаём целочисленные переменные
    while (a_now < 100){ // запускаем цикл while
        printf("%d ", a_now); // выписываем очередной элемент последовательности
        a_now = a_before + i; // вычисляем следующий элемент последовательности
        a_before = a_now; // переопределяем предыдущий элемент последовательности
        i++; // увеличиваем порядковый номер элемента последовательности
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
1 3 6 10 15 21 28 36 45 55 66 78 91
Process returned 0 (0x0)   execution time : 0.010 s
Press any key to continue.

2Задача №2.

Выписать последовательность чисел Фибоначчи до 10000.

Последовательность Фибоначчи строится по правилу:
a_n  = \left\{ \begin{gathered} 0, \hspace{0.3cm} n=0, \\ 1, \hspace{0.3cm} n=1, \\ a_{n-1} + a_{n-2}, \hspace{0.3cm} n > 1, \\ \end{gathered} \right.
Таким образом, её начало имеет вид: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int a_now = 1, a_before = 1, a_before_before = 0; // создаём целочисленные переменные
    printf("0 "); // выписываем самое первое число в последовательности Фибоначчи
    while (a_now < 10000){ // запускаем цикл while
        printf("%d ", a_now); // выписываем очередной элемент последовательности Фибоначчи
        a_now = a_before + a_before_before; // вычисляем следующий элемент последовательности Фибоначчи
        a_before_before = a_before; // переопределяем пред предыдущий элемент последовательности Фибоначчи
        a_before = a_now; // переопределяем предыдущий элемент последовательности Фибоначчи
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
Process returned 0 (0x0)   execution time : 0.008 s
Press any key to continue.

3Задача №3.

Пользователь вводит целое число. Необходимо выписать на экран его сумму цифр.
Не забудьте, что пользователь может ввести отрицательное число.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h
#include <math.h> // подключаем библиотеку math.h

int main(){ // создаём главную функцию
    int x = 0, s = 0; // создаём целочисленные переменные
    printf("Print 1 number: "); // приглашаем пользователя на ввод
    if (scanf("%d", &x) != 1){ // если число считано корректно
        printf("Reading error.\n"); // уведомляем пользователя об ошибке чтения в случае некорректного считывания
        return -1; // возвращаем -1, если не установлен другой код ошибки чтения
    }
    x = abs(x); // избавляемся от минуса перед числом пользователя, если он есть
    while (x > 0){ // запускаем цикл while
        s += x % 10; // прибавляем к переменной s последнюю цифру числа х
        x /= 10; // делим число х на 10 в целых числах
    }
    printf("%d\n", s); // выписываем ответ
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print 1 number: -786123
27

Process returned 0 (0x0)   execution time : 3.015 s
Press any key to continue.

4Задача №4.

Написать программу, выписывающую сумму цифр числа, введённого пользователем, пока пользователь вводит числа. Как только пользователь введёт какой-нибудь символ, программа должна завершиться, попрощавшись с пользователем.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h
#include <math.h> // подключаем библиотеку math.h

int main(){ // создаём главную функцию
    int x = 0, s = 0; // создаём целочисленные переменные
    while (true){ // запускаем бесконечный цикл while
        printf("Print the number: "); // приглашаем пользователя на ввод
        if (scanf("%d", &x) != 1){ // если число считано корректно
            printf("Goodbye!\n"); // прощаемся с пользователем
            return 0; // возвращаем 0 - успех
        }
        x = abs(x); // избавляемся от минуса перед числом пользователя, если он есть
        s = 0; // обнуляем сумму
        while (x > 0){ // пока переменная х больше нуля
            s += x % 10; // прибавляем к переменной s последнюю цифру числа х
            x /= 10; // делим число х на 10 в целых числах
        }
        printf("%d\n", s); // выписываем ответ
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print the number: 12
3
Print the number: 25
7
Print the number: 89
17
Print the number: 190
10
Print the number: q
Goodbye!

Process returned 0 (0x0)   execution time : 8.165 s
Press any key to continue.

5Задача №5.

Среди пяти введённых пользователем целых чисел найти число, имеющее максимальную сумму цифр. Выписать это число и сумму его цифр.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h
#include <math.h> // подключаем библиотеку math.h

int main(){ // создаём главную функцию
    int x = 0, x_max = 0, s = 0, s_max = 0, temp = 0; // создаём целочисленные переменные
    printf("Print 5 numbers: "); // приглашаем пользователя на ввод
    for (int i = 0; i < 5; i++){ // запускаем цикл for
        if (scanf("%d", &x) != 1){ // если число считано корректно
            printf("Reading error.\n"); // уведомляем пользователя об ошибке чтения в случае некорректного считывания
            return -1; // возвращаем -1, если не установлен другой код ошибки чтения
        }
        temp = abs(x); // сохраняем копию переменной х
        s = 0; // обнуляем сумму
        while (temp > 0){ // пока переменная temp больше нуля
            s += temp % 10; // прибавляем к переменной s последнюю цифру числа temp
            temp /= 10; // делим число temp на 10 в целых числах
        }
        if (s > s_max){ // если получившаяся сумма больше максимальной
            s_max = s; // обновляем максимальную сумму цифр
            x_max = x; // обновляем представителя
        }
    }
    printf("%d has the biggest digits sum %d\n", x_max, s_max); // выписываем ответ
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print 5 numbers: 123 -34 -721 367 11223
367 has the biggest digits sum 16

Process returned 0 (0x0)   execution time : 13.544 s
Press any key to continue.

6Задача №6.

Найти с точностью до 3-х цифр после точки среднее арифметическое сумм цифр среди чисел от 1 до 100, от 1 до 1000 и от 1 до 10000. Сделать вывод о закономерности средней суммы цифр.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int s = 0, temp = 0; // создаём целочисленные переменные
    for (int i = 1; i < 100; i++){ // запускаем цикл for
        temp = i; // сохраняем копию переменной х
        while (temp > 0){ // пока переменная temp больше нуля
            s += temp % 10; // прибавляем к переменной s последнюю цифру числа temp
            temp /= 10; // делим число temp на 10 в целых числах
        }
    }
    printf("The average among the digits sum from 1 to 100 is %.3f\n", double(s) / 100.0); // выписываем ответ
    s = 0; // обнуляем сумму
    for (int i = 1; i < 1000; i++){ // запускаем цикл for
        temp = i; // сохраняем копию переменной х
        while (temp > 0){ // пока переменная temp больше нуля
            s += temp % 10; // прибавляем к переменной s последнюю цифру числа temp
            temp /= 10; // делим число temp на 10 в целых числах
        }
    }
    printf("The average among the digits sum from 1 to 1000 is %.3f\n", double(s) / 1000.0); // выписываем ответ
    s = 0; // обнуляем сумму
    for (int i = 1; i < 10000; i++){ // запускаем цикл for
        temp = i; // сохраняем копию переменной х
        while (temp > 0){ // пока переменная temp больше нуля
            s += temp % 10; // прибавляем к переменной s последнюю цифру числа temp
            temp /= 10; // делим число temp на 10 в целых числах
        }
    }
    printf("The average among the digits sum from 1 to 10000 is %.3f\n", double(s) / 10000.0); // выписываем ответ
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
The average among the digits sum from 1 to 100 is 9.000
The average among the digits sum from 1 to 1000 is 13.500
The average among the digits sum from 1 to 10000 is 18.000

Process returned 0 (0x0)   execution time : 0.008 s
Press any key to continue.

7Задача №7.

Сначала пользователь вводит число — максимально возможный переносимый вес в килограммах, который он сможет унести в своём рюкзаке. Затем пользователь последовательно вводит массы грузов, которые он намерен положить в свой рюкзак. Необходимо после каждого груза сообщать пользователю, что он может его взять, пока общая масса грузов в его рюкзаке не превосходит максимально возможный переносимый вес. Как только общая масса грузов в его рюкзаке превысит максимально допустимую, необходимо остановить программу и выписать, какую массу грузов в итоге набрал пользователь и количество набранных им грузов.
Не забудьте проверить, что все массы - положительные числа.
Решение:
#include <stdio.h> // подключаем библиотеку stdio.h
#include <stdlib.h> // подключаем библиотеку stdlib.h

int main(){ // создаём главную функцию
    int M = 0, m = 0, count = 0, t = 0; // создаём целочисленные переменные
    printf("Print your max mass: "); // приглашаем пользователя на ввод
    if (scanf("%d", &M) != 1){ // если число считано корректно
        printf("Reading error.\n"); // уведомляем пользователя об ошибке чтения в случае некорректного считывания
        return -1; // возвращаем -1, если не установлен другой код ошибки чтения
    }
    if (M <= 0){ // проверяем корректность введённого числа
        printf("The incorrect max mass.\n"); // уведомляем пользователя о некорректности введённого числа
        return -2; // возвращаем -2, если не установлен другой код ошибки данных
    }
    while (true){ // запускаем бесконечный цикл while
        printf("Print the mass of load you wanna take: "); // приглашаем пользователя на ввод
        if (scanf("%d", &m) != 1){ // если число считано корректно
            printf("Goodbye!\n"); // прощаемся с пользователем
            return 0; // возвращаем 0 - успех
        }
        if (m <= 0){ // проверяем корректность введённого числа
            printf("The incorrect mass of load.\n"); // уведомляем пользователя о некорректности введённого числа
            return -2; // возвращаем -2, если не установлен другой код ошибки данных
        }
        if (t + m > M){ // если данный груз взять нельзя
            printf("You cannot take this load\n\nSo you have taken %d loads with a total weight of %d kg\n", count, t); // пишем пользователю, сколько он взял грузов и какой суммарной массы
            return 0; // возвращаем 0 - успех
        } else { // иначе
            t += m; // увеличиваем текущую массу рюкзака пользователя
            count++; // увеличиваем количество взятых грузов
            printf("You can take this load\n"); // пишем пользователю, что он может взять данный груз
        }
    }
    return 0; // возвращаем 0 - успех
}
Пример работы программы:
Print your max mass: 35
Print the mass of load you wanna take: 10
You can take this load
Print the mass of load you wanna take: 12
You can take this load
Print the mass of load you wanna take: 15
You cannot take this load

So you have taken 2 loads with a total weight of 22 kg

Process returned 0 (0x0)   execution time : 11.773 s
Press any key to continue.

8Задача №8*.

Пользователь вводит число - сумму денег, которую он хотел бы разменять на более мелкие купюры. Необходимо выписать количество всевозможных различных способов размена суммы пользователя купюрами, достоинством 100₽, 500₽ и 1000₽.
Например, 5000₽ можно разменять пятью купюрами по 1000₽ или тремя купюрами номиналом 1000₽ и четырьмя — номиналом 500₽. А в задаче необходимо посчитать количество всех возможных способов размена суммы пользователя.
Решение:

Для достижения наилучшего результата и доступа ко всему курсу необходимо приобрести курс еженедельных индивидуальных или групповых занятий с преподавателем в режиме онлайн. Наши преподаватели обучат Вас создавать уникальные алгоритмы и самостоятельно реализовывать их в программном коде с соблюдением стандартов оформления.

Для записи на бесплатный пробный урок просто заполните форму ниже: