Задания по С++

№1 Устанавливаем C++ Code::Blocks

Для написания программ будем использовать среду разработки (так называемую IDE) C++ Code::Blocks. Среда разработки облегчает работу с кодом программы, а также процесс компиляции (то есть преобразования кода в исполняемый файл, тот самый *.exe). Без IDE программы пришлось бы писать в блокнотике, а копилировать через командную строку, используя страшные и непонятные заклинания типа:

mingw32-g++.exe -Wall -fexceptions -g  -c main.cpp -o obj\Debug\main.o
mingw32-g++.exe  -o bin\Debug\Project1.exe obj\Debug\main.o

в общем среда разработки берет все это на себя, а нам остается только писать код и время от времени запускать сборку программы нажимаю одну простую кнопку. Что есть хорошо.

C++ Code::Blocks – не единственная IDE для разработки на C++, на самом деле их там тьма. Среди наиболее популярных:

  • Visual Studio
  • Qt Creator
  • CLion

все они умеют примерно одно и тоже, и выбор среды разработки есть скорее дело вкуса. Я выбрал C++ Code::Blocks, потому что ее можно скачать и запускать хоть с флешки, Qt Creator вроде тоже так может но он весит 2GB, так что ну его…

И так, качаем C++ Code::Blocks тут: http://www.codeblocks.org/downloads/26 (а если вы на паре, то просим у меня флешку с IDE)

№2 Создаем первое приложение

Запускаем C++ Code::Blocks

если выскочит окно:

жмем Ok.

Далее если выскочит такое окно, то также жмем ок,

кликаем Create a new Project

Далее выбираем Console Application (то бишь консольное приложение, которое работает в командной строке)

жмем Go, откроется визард (мастер, типа упрощенный способ создания приложение) для создания проекта, жмем Next

выбираем C++ если не выбран, жмем Next

далее, заполняем два поля, название проекта, и выбираем папку где будет создан проект, остальные поля должны будут заполниться самостоятельно

на следующей странице ничего не меняем и жмем Finish

откроется наш проект, в дереве проекта раскрываем узел Sources и кликам два раза на main.cpp

Открывается код программы

#include <iostream> // это подключение библиотек для работы с консолью

using namespace std; // это подключение пространства имен (пока не будем об этом думать)

int main() // главная функция, любая программа на C++ начинается с этой функции
{
    cout << "Hello world!" << endl; // это первая строчка которая выполнится когда мы запустим программу
                                    // в ней написано отправить в cout (который подключен к консоли) текст "Hello world!"
                                    // то есть, проще говоря, отправить в консоль текст "Hello world!"
                                    // или, еще проще, вывести "Hello world!" на экран консоли
                                    // << - это знак позволяет отправить что-то куда-то,
                                    // есть еще >> который позволяет что-то взять из консоли, например если пользователь что-то ввел
                                    // но о нем позже.
                                    // endl - отправляет в консоль перенос на новую строку,
                                    // то есть просто добавляет новую строку в консоль

    return 0; // функция в C++ должна что-нибудь вернуть,
              // согласно правилу хорошего стиля, корректно завершившееся приложение должно вернуть 0
}

запускаем приложение:

любуемся результатом:

Поздравляю, теперь вы знаете C++!!! =)

№3 Математические функции

Вот вам методичка: скачать, я ее немного подкорректировал, там в конце задания их надо выполнить. Под каждое задание создавать отдельный проект, чтобы процесс был доведен до автоматизма.

Все задания требуют от пользователя ввода каких-то данных в консоль, запрос на ввод организуется путем использования устройства ввода. Доступа, к которому организуется через cin, допустим я хочу, чтобы пользователь ввел два числа, а я ему в ответ вывел сумму этих чисел, сделаю я это так

#include <iostream>

using namespace std;

int main()
{
    int a, b; // объявил две переменные

    cin >> a >> b; // запросил их у пользователя, 
                   // значения должны быть разделены пробелом
    cout << "sum is " << a + b << endl; // вывел на экран их сумму

    return 0;
}

проверим:

Так же в части заданий нужно будет использовать математические функции, для этого потребуется сначала подключить хэдер (header) для доступа к ним. Допустим я хочу проверить основное тригонометрическое тождество . Сделаю я это так:

#include <iostream>
#include <math.h> // подключил математические функции

using namespace std;

int main()
{
    int angle;

    cout << "введите значение угла" << endl; // прошу пользователя что-нибудь ввести
    cin >> angle; // сохраняю ввод пользователя в переменную

    // перевожу угол в радианы и сохраняю результат в переменную angleInRadians
    float angleInRadians = M_PI * angle / 180 ;

    // расчитываю основное тригонометрическое тождество
    // cos и sin -- это понятно что за функции
    // pow -- это функцию у которой два параметра, первый число которое мы возводим,
    // а второй степень в которую возводим.
    // Тут я в первый параметр подставляю значение cos/sin соответственно
    float result = pow(cos(angleInRadians), 2) + pow(sin(angleInRadians), 2);

    // вывожу результат, сразу несколько значений, C++ не чувствителен к пробелам и переносам
    // поэтому иногда разумно написать код красиво
    cout << "angle is: " << angle << endl
         << "angle in radians: " <<  angleInRadians << endl
         << "cos^2(x) + sin^2(x) = " << result << endl;

    return 0;
}

проверим:

хм, какие-то кракозябры вместо букв, чтобы русский текст отображался корректно надо сделать следующее:

открываем вкладку other compiler options и вводим там

-finput-charset=cp1251
-fexec-charset=cp866

пересобираем проект

а дальше запускаем как обычно:

№4 Условный оператор if

Задания

  1. Даны числа . Проверить истинность высказывания: «Точка с координатами лежит во второй или третьей координатной четверти».
  2. Дано целое число, лежащее в диапазоне 1–999. Вывести его описание вида «четное двузначное число», «нечетное трехзначное число» и т. д.
  3. Даны уравнения двух прямых и . Определить, пересекаются ли эти прямые, совпадают или параллельны.

Как это делать

Условный оператора это контрукция if-else вида:

if (<условие1>) {
    // последовательность действий при истиности <условия1>
} else {
    // последовательность действий при ложности <условия1>
}

либо если хочется проверить что-то на целый каскад условий можно писать так:

if (<условие1>) {
    // последовательность действий при истиности <условия1>
} else if (<условие2>) {
    // последовательность действий при истиности <условия2>
} else if (<условие3>) {
    // последовательность действий при истиности <условия3>
} else {
    // последовательность действий в случае если все три условия оказались ложными
}

Понятно что в жизни вместо <условие#> подставляется какое-то выражение. Пример:

#include <iostream>

using namespace std;

int main()
{
    int number = 10;

    if (number == 10) { // да-да, проверка на равенство это двойное равно
        cout << number << " равно 10" << endl;
    }

    if (number != 11) { // используя восклицательный знак, пишем проверку на неравенство
        cout << number << " не равно 11" << endl;
    }

    if (number >= 8) {
        cout << number << " больше или равно чем 8" << endl;
    }

    if (-100 < number && number < 100) { // две амперсанда (&) означают ЛОГИЧЕСКОЕ И
        cout << number << " находится в промежутке (-100; 100)" << endl;
    }
    
    if (number <= -100 || 100 <= number ) { // две вертикальные палки означают ЛОГИЧЕСКОЕ ИЛИ
        cout << number << " находится вне промежутка [-100; 100]" << endl;
    }
    
    if (number % 5 == 0) { // знак  процента -- это оператор для нахождения остатка от деления левого числа на правое
        cout << number << " делится на 5 без остатка" << endl;
    }
    
    if (number % 2 == 1) { 
        // это выражение не выполнится 
        // так как number % 2 == 1 не является истиииным условием
        cout << number << " нечетное число" << endl; 
    } else {
        // зато вот это выполнится
        // так как number % 2 == 1 ложно
        cout << number << " четное число" << endl;
    }
    
    return 0;
}

№5 Оператор выбора switch

Задания

  1. Написать программу, которая по числу от 1 до 10 выдаст название числа.
  2. Единицы длины пронумерованы следующим образом: 1 — дециметр, 2 — километр, 3 — метр, 4 — миллиметр, 5 — сантиметр. Дан номер единицы длины (целое число в диапазоне 1–5) и длина отрезка в этих единицах (вещественное число). Найти длину отрезка в метрах.
  3. Элементы окружности пронумерованы следующим образом: 1 — радиус , 2 — диаметр , 3 — длина , 4 — площадь круга . Дан номер одного из этих элементов и его значение. Вывести значения остальных элементов данной окружности (в том же порядке).

Как это делать

Оператор выбора используется в конструкции:

switch (<какая_та_переменная_величина>){
    case <значение1>:
        // что-то делаем если <какая_та_переменная_величина> равна <значению1>
        break; // каждый case должне заканчиваться брейком
    case <значение2>:
    case <значение3>:
        // что-то делаем если <какая_та_переменная_величина> равна либо <значению2> либо <значению3>
        break;
    default:
        // если <какая_та_переменная_величина> не равна ни <значению1>, ни <значению2>, ни <значению3>
}

В природе выглядит как-то так:

#include <iostream>

using namespace std;

int main()
{
    int mark;

    cout << "Введите значение оценки" << endl;
    cin >> mark;

    switch(mark)
    {
        case 2:
        case 3:
            cout << "Стипендии не будет." << endl;
            break;
        case 4:
            cout <<  "Ура! Стипендия будет." << endl;
            break;
        case 5:
            cout << "Гуляем по полной!" << endl;
            break;
        default:
            cout << "Неверное значение оценки..." << endl;
            break;
    }
    return 0;
}

№6 Работа с массивами и цикл for

Задания

  1. Дан массив . Запросить у пользователя элементы массива и найти сумму квадратов этих чисел.
  2. Дан массив . Запросить у пользователя элементы массива и найти произведение этих чисел.
  3. Найти n-факторил, значение n запрашивать у пользователя
  4. Дан массив . Запросить у пользователя элементы массива и вывести на экран нечетные числа.
  5. Дан массив , числа A и B. Запросить у пользователя элементы массива и подсчитать количество элементов , которые попадают в промежуток .

Как это делать

Чтобы объявить массив в C++ надо писать следующим образом (так как мы все пишем внутри функции main, я буду писать только ее содержимое) :

int numbers[]  = {1,2,3,4,5}; // объявляем массив

// индексация с нуля, так что 
cout << numbers[0] << endl; // данная строчка выведет первый элемент массива
cout << numbers[1] << endl; // выведет 2-ой элемент массива
cout << numbers[2] << endl; // выведет 3-ий элемент массива
cout << numbers[3] << endl; // выведет 4-ый элемент массива
cout << numbers[4] << endl; // выведет 5-ый элемент массива
return 0;

часто бывают ситуации когда, начальные значения массива неизвестны, и должны быть введены пользователем, тогда можно просто объявить массив строго заданной величины.

int numbers[3]; // объявляем массив размерности 3

// сохраняем значения введенные пользователем в массив
cin >> numbers[0] >> numbers[1] >> numbers[2];

// выводим сумму элементов массива
cout << numbers[0] + numbers[1] + numbers[2];

return 0;

а теперь давайте поговорим о циклах. Циклы сильно упрощают работу с массивами. давайте модернезируем нашу программку выше, и так пусть нам дано:

int numbers[5]; // объявляем массив размерности 5

// сохраняем значения введенные пользователем в массив
cin >> numbers[0];
cin >> numbers[1];
cin >> numbers[2];
cin >> numbers[3];
cin >> numbers[4];

// считаем сумму элементов
int sum = numbers[0] 
        + numbers[1] 
        + numbers[2] 
        + numbers[3] 
        + numbers[4];

// выводим сумму элементов массива
cout << sum;

return 0;

рассмотрим строки

cin >> numbers[0];
cin >> numbers[1];
cin >> numbers[2];
cin >> numbers[3];
cin >> numbers[4];

как видно все эти строчки отличаются только индексом. Давайте воспользуемся циклом, чтобы упростить эту запись, и так получится:

for (int i=0;i<=4;++i) {
    cin >> numbers[i]; // то что находится в фигурных скобках называется ТЕЛОМ ЦИКЛА 
}
  • for это оператор цикла. После оператора цикла с скобочках указывается структура из трех выражений, разделенных точкой запятой.
  • Первое выражение int i=0; – это инициализация переменной i, с начальным значением ноль, она будет использоваться в качестве так называемого счетчика
  • i<=4 – пока это условие истинно будет выполнятся тело цикла, обычно используют строгие неравенства, то есть это же условие можно написать как i<5
  • ++i – команда которая выполнятся в конце каждой итерации цикла, в данном случае тут ничего хитрого просто увеличение значения счетчика на 1.

Разберем пошагово как сработает код с циклом

  1. Сначала создается переменная i, и ей присваивается значение 0
  2. Проверятся условие i<=4? Так как i равно 0, то проверяется 0<=4? Так как это условие верно переходим к телу цикла
  3. В теле цикла вместо i подставляется 0, и вызывается команда cin >> numbers[0]. То есть просто запрос у пользователя нулевого элемента
  4. Так как больше команд в теле цикла нет, то вызывется выражение ++i, которое увеличивает значение i на единицу, то есть i теперь равно 1.
  5. Снова проверяется i<=4? Так как i равно 1, то проверяется 1<=4? Так как это условие верно переходим к телу цикла
  6. В теле цикла вместо i подставляется 1, и вызывается команда cin >> numbers[1]. То есть просто запрос у пользователя первого элемента
  7. Так как больше команд в теле цикла нет, то вызывется выражение ++i, которое увеличивает значение i на единицу, то есть i теперь равно 2.
  8. Снова проверяется i<=4? Так как i равно 2, то проверяется 2<=4? Так как это условие верно переходим к телу цикла
  9. В теле цикла вместо i подставляется 2, и вызывается команда cin >> numbers[2]. То есть просто запрос у пользователя второго элемента
  10. Так как больше команд в теле цикла нет, то вызывется выражение ++i, которое увеличивает значение i на единицу, то есть i теперь равно 3.
  11. Снова проверяется i<=4? Так как i равно 3, то проверяется 3<=4? Так как это условие верно переходим к телу цикла
  12. В теле цикла вместо i подставляется 3, и вызывается команда cin >> numbers[3]. То есть просто запрос у пользователя третьего элемента
  13. Так как больше команд в теле цикла нет, то вызывется выражение ++i, которое увеличивает значение i на единицу, то есть i теперь равно 4.
  14. Снова проверяется i<=4? Так как i равно 4, то проверяется 4<=4? Так как это условие верно переходим к телу цикла
  15. В теле цикла вместо i подставляется 4, и вызывается команда cin >> numbers[4]. То есть просто запрос у пользователя четвертого элемента
  16. Так как больше команд в теле цикла нет, то вызывется выражение ++i, которое увеличивает значение i на единицу, то есть i теперь равно 5.
  17. Снова проверяется i<=4? Так как i равно 5, то проверяется 5<=4? Так как это условие ложно то цикл завершает свою работу.

Собственно так и работает цикл. При работе с массивами он не заменим. Кстати давайте добавим строчку которая будет предлагать ввести пользователю i-ый элемент и заменим условие i<=4 на эквивалентное i<5. Вот так:

for (int i=0;i<5;++i) {
    cout << "Введите " << i + 1 << " элемент" << endl;
    cin >> numbers[i];
}

Вот как должен выглядеть наш код сейчас:

#include <iostream>

using namespace std;

int main()
{
    int numbers[5]; // объявляем массив размерности 5

    // сохраняем значения введенные пользователем в массив
    for (int i=0;i<=4;++i) {
        cout << "Введите " << i << " элемент" << endl;
        cin >> numbers[i];
    }

    // считаем сумму элементов
    int sum = numbers[0]
            + numbers[1]
            + numbers[2]
            + numbers[3]
            + numbers[4];

    // выводим сумму элементов массива
    cout << sum;

    return 0;
}

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

заменим

int sum = numbers[0]
        + numbers[1]
        + numbers[2]
        + numbers[3]
        + numbers[4];

на

int sum  = 0; // объявляем переменную sum и инициализируем ее нулем

sum = numbers[0]
    + numbers[1]
    + numbers[2]
    + numbers[3]
    + numbers[4];

вот эта большая сумма может быть разбита на несколько маленьких:

int sum  = 0;

sum = sum + numbers[0];
sum = sum + numbers[1];
sum = sum + numbers[2];
sum = sum + numbers[3];
sum = sum + numbers[4];

эту запись можно написать более компактно

int sum  = 0;

sum += numbers[0];
sum += numbers[1];
sum += numbers[2];
sum += numbers[3];
sum += numbers[4];

тут уже явно прослеживается наличие цикла, заменяем

int sum  = 0; // объявляем переменную sum и инициализируем ее нулем

for (int i=0;i<5;++i) {
    sum += numbers[i];
}

и собственно и все.

Вот такой код у нас в итоге получается:

#include <iostream>

using namespace std;

int main()
{
    int numbers[5]; // объявляем массив размерности 5

    // сохраняем значения введенные пользователем в массив
    for (int i=0;i<5;++i) {
        cout << "Введите " << i << " элемент" << endl;
        cin >> numbers[i];
    }

    int sum  = 0; // объявляем переменную sum и инициализируем ее нулем

    for (int i=0;i<5;++i) {
        sum += numbers[i];
    }
    // выводим сумму элементов массива
    cout << sum;

    return 0;
}

№7 Работа с матрицами

Задачи

  1. Дана матрица 3x3, запросить значения у пользователя и найти определитель.
  2. Дана матрица произвольного размера, запросить у пользвателя ее размеры, рассчитать транспонированую матрицу, и вывести ее на экран
  3. Даны две матрицы A и B одинакового размера, найти матрицу A+B, и вывести ее на экран
  4. Дана квадратная матрица порядка n. Найти номера строк, все элементы которых нули.

Как это делать

Чтобы объявить матрицу, в отличие от масcива, надо использовать две квадратных скобки:

#include <iostream>

using namespace std;

int main()
{
    int A[3][3] = {{1,2,3}, {3,4,5}, {5,6,7}}; // объявили матрицу три на три

    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    cout << A[0][0] << endl; 
    cout << A[0][1] << endl; 
    cout << A[0][2] << endl; 
    cout << A[1][0] << endl; 
    cout << A[1][1] << endl; 
    cout << A[1][2] << endl; 
    cout << A[2][0] << endl; 
    cout << A[2][1] << endl; 
    cout << A[2][2] << endl; 

    return 0;
}

Обычно с матрицей работают сразу по всем строкам, поэтому удобно использовать циклы, тот же пример что и выше но и с использование цикла

#include <iostream>

using namespace std;

int main()
{
    int A[3][3] = {{1,2,3}, {3,4,5}, {5,6,7}}; // объявили матрицу три на три

    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    for (int i=0;i<3;++i) { // проходим по всем строкам
        cout << A[i][0] << endl; // выводим первый элемент i-ой строки
        cout << A[i][1] << endl; // выводим второй элемент i-ой строки
        cout << A[i][2] << endl; // выводим третий элемент i-ой строки
    } 

    return 0;
}

тут кстати напрашивается еще один цикл, по элементам строки. Это просто организовать путем вложения одного for в другой, вот так:

#include <iostream>

using namespace std;

int main()
{
    int A[3][3] = {{1,2,3}, {3,4,5}, {5,6,7}}; // объявили матрицу три на три

    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    for (int i=0;i<3;++i) { // проходим по всем строкам
        for (int j=0;j<3;++j) { // проходим по всем элементам строки
            cout << A[i][j] << endl; 
        } 
    } 

    return 0;
}

чтобы вывод был похож на матрицу, а не на столбик перепишем

#include <iostream>

using namespace std;

int main()
{
    int A[3][3] = {{1,2,3}, {3,4,5}, {5,6,7}}; // объявили матрицу три на три

    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    for (int i=0;i<3;++i) { // проходим по всем строкам
        for (int j=0;j<3;++j) { // проходим по всем элементам строки
            cout << A[i][j] << " "; 
        } 
        cout << endl;
    } 
    return 0;
}

Значение элементов матрицы можно изменять путем оператора присваивания, вот так

#include <iostream>

using namespace std;

int main()
{
    int A[3][3] = {{1,2,3}, {3,4,5}, {5,6,7}}; // объявили матрицу три на три

    A[1][1] = 0; // присвоили 0 второму элементу, второй строки
                 // теперь в A матрица {{1,2,3}, {3,0,5}, {5,6,7}}

}

можно например таблицу умножения сделать:

#include <iostream>

using namespace std;

int main()
{
    int A[5][5]; // объявили пустую матрицу три на три

    // рассчитываем таблицу умножения
    for (int i=0;i<5;++i) {
        for (int j=0;j<5;++j) {
            A[i][j] = (i + 1) * (j + 1); // заполняем матрицу
        } 
    } 


    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    for (int i=0;i<5;++i) { // проходим по всем строкам
        for (int j=0;j<5;++j) { // проходим по всем элементам строки
            cout << A[i][j] << "\t"; // тут использую знак табуляции, чтобы выводи был по красивше
        } 
        cout << endl;
    } 

    /*
        В консоли увидим:

        1       2       3       4       5
        2       4       6       8       10
        3       6       9       12      15
        4       8       12      16      20
        5       10      15      20      25
    */

    return 0;
}

часто надо работать с матрицей произвольного размера, в этом случае надо сначала запросить у пользователя размеры а потом уже создать матрицу, например так.

#include <iostream>

using namespace std;

int main()
{
    int N,M;
    cout << "Укажите размеры матрицы N и M через пробел: ";
    cin >> N >> M;

    int A[N][M]; // объявили пустую матрицу указаного пользователем размера

    // рассчитываем таблицу умножения
    for (int i=0;i<N;++i) {
        for (int j=0;j<M;++j) {
            A[i][j] = (i + 1) * (j + 1); // заполняем матрицу
        }
    }

    // вывести на экран содержимое каждого элемента, нумерация как и в массиве с нуля
    for (int i=0;i<N;++i) { // проходим по всем строкам
        for (int j=0;j<M;++j) { // проходим по всем элементам строки
            cout << A[i][j] << "\t";
        }
        cout << endl;
    }

    return 0;
}

№8 Цикл while

Задания

1) Используя разложение в ряд Лейбница рассчитать значение с заданым порядком (пока разница между значениями полученными на следующей и предыдущей итерации не достигнет заданого порядка)

2) Расчитать значение экспоненты с заданой точностью (пока разница между значениями полученными на следующей и предыдущей итерации не достигнет заданого порядка)

3) Реализовать рассчет бесконечной суммы, каждое новое число пользователь вводит с клавиатуры, программа останавливается если пользователь ввел 0

4*) Реализовать игру в угадывание числа, компьютер загадывает число с помощью конструкции rand() % 100, пользователь же должен угадать число. Если юзер ввел число больше (меньше) загаданого выдается сообщение о том что число больше (меньше), если пользователь угадал число выводится сообщение с поздравлением.

Как это делать

В С++ помимо цикла for есть альтернативный способ создания циклов while, в большинстве случаев его использование не оправдано либо может быть выражено через for. Однако есть ситуации когда применение while упрощает восприятие кода.

Самый простой пример, это бесконечный цикл:

#include <iostream>

using namespace std;

int main()
{
    string answer; // переменная куда будем фиксировать введенную пользователем букву
    while(true) { // выполнять цикл бесконечно
        // запрашиваем у пользователя букву y или n
        cout << "Продолжить цикл (y/n)?" << endl;
        cin >> answer;
        // если пользователь ввел n
        if (answer == "n") {
            break; // выходим из цикла (break -- один из способов прервать выполенениецикл)
        }
    }
}

еще одно удачное применение цикла while это рассчет значений с некоторой точностью. Например, я расчитаю сумму бесконечно убывающей геометрической прогрессии при :

до какого знака (или иначе говоря до какого порядка), я запрошу у пользователя

#include <iostream>
#include <math.h>
#include <iomanip> // ДОБАВИТЬ ЧТОБЫ БЫЛА ВОЗМОЖНОСТЬ БОЛЕЕ ТОНКО КОНТРОЛИРОВАТЬ ВЫВОД В КОНСОЛЬ

using namespace std;

int main()
{
    int n;
    cout << "Введите до какой цифры после запятой следует рассчитать значение: " << endl;
    cin >> n;
    double order = 1.0 / pow(10, n); // так называемая невязка или точность, это даст нам 0.1 для n == 1, 0.001 для n==2 и т.д.

    double q = 0.5; // это знаменатель прогрессии, можете какой-нибудь свой подставить, главное чтобы меньше 1

    // придется хранить две итерации суммы
    double previous_sum = pow(q, 0); // так называемую предыдущую, значение нулевой итерации
    double sum = previous_sum + pow(q, 1); // и текущую, значение первой итерации + значение нулевой
    double k = 2; // отсчет начинаем с 2, так как нулевую и первую итерацию уже рассчитали выше

    // проверяем разницу между текущей и следующей рассчитанной суммой, если она превышает заданную точность
    while(fabs(previous_sum - sum) > order) {
        // пересчитываем суммы, предудущую инициализируем текущей,
        // на следующей итерацией она уже снова будет предыдущей
        previous_sum = sum;
        sum += pow(q, k); // и пересчитываем текущую сумму

        k++; // увеличиваем счетчик
    }

    cout << "Ответ: "
         << setprecision(n + 3) // функция, которая указывает сколько знаков после запятой выводить у числа
         << sum  // выводим сумму
         << endl; // новая строка
    return 0;
}

№9 Функции

Задание

  1. Дано три массива чисел размерностью 4, найти произведение средних арифметических значений этих массивов. Для расчета среднего арифметического написать функцию.
  2. Дано три числа найти сумму факториалов . Для расчета факториала написать функцию
  3. Дано три числа найти сумму сумм первых a(b,c) членов арифметической прогрессий . Для расчета арифметической прогрессии написать функцию
  4. Дано три точки в пространстве, рассчитать периметр треугольника лежащего на этих точках. Для рассчета длины отрезка написать функцию.

Как это делать

Использование функций это хороший способ более грамотно организовать код. В функцию часто выносят какие-то повторяющиеся действия.

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

эту функцию нельзя убрать. А вот добавить новую нам никто не мешает. Рассмотрим пару примеров.

Допустим нам дали несколько массивов и хотят чтобы мы рассчитали сумму каждого из списков. Попробуем написать это код сначала без функций:

#include <iostream>

using namespace std;

int main()
{
    int A[] = {1,2,3};
    int B[] = {4,5,6,7};
    int C[] = {8,9};
    
    int sumA = 0;
    for (int i=0;i<3;++i) {
        sumA += A[i]
    }
    
    int sumB = 0;
    for (int i=0;i<4;++i) {
        sumB += B[i]
    }
    
    int sumC = 0;
    for (int i=0;i<2;++i) {
        sumC += C[i]
    }
    
    return 0;
}

тут видно что рассчет всех сумм отличается по сути только количеством элементов и используемыми переменными, логика же везде одинаковая. Это явные признак что данные куски кода можно как-то обобщить и утащить в функцию. Сделаем это.

В С++ важен порядок объявления функций. То есть тут как и с переменными, вы не можете использовать переменную до того как объявили ее, и так же вы не можете использовать функцию в куске кода который находится раньше непосредственного объявления функции.

Поэтому функцию мы будем добавлять между using namespace std; и int main(), выглядеть это будет вот так:

#include <iostream>

using namespace std;

int calculateSum(int arr[], int length) // добавили функцию
{
    int sum = 0;
    for (int i=0;i<length;++i) {
        sum += arr[i];
    }
    return sum;
}


// это пока не трогаем...
int main()
{
    //...
}

теперь давайте перепишем код функции main, чтобы он начал использовать нашу функцию. Получится:

#include <iostream>

using namespace std;

int calculateSum(int arr[], int length)
{
    int sum = 0;
    for (int i=0;i<length;++i) {
        sum += arr[i];
    }
    return sum;
}

int main()
{
    int A[] = {1,2,3};
    int B[] = {4,5,6,7};
    int C[] = {8,9};

    // заменили на использование функции
    int sumA = calculateSum(A, 3);
    int sumB = calculateSum(B, 4);
    int sumC = calculateSum(C, 2);
    
    cout << "sumA: " << sumA << endl;
    cout << "sumB: " << sumB << endl;
    cout << "sumC: " << sumC << endl;

    return 0;
}

если не понятно как это работает, вот вам схема, которая возможна упростит понимание, того каким образом передаются и возвращаются параметры

№10 STL и чуток современного С++

Задания

  1. Доработать игру в угадайку, в случае угадывания числа, выводить все числа которые вводил пользователь
  2. Запросить у пользователя произвольное количество чисел (считать что пользователь больше не хочет вводить числа если он ввел 0). Вывести на экран сначала положительные числа, а потом отрицательные.
  3. Найти среднее арифметическое значение максимального и минимального элементов в массиве
  4. Найти максимальное среди минимальных значений матрицы. Использовать библиотчечку algorithm
  5. Подсчитать сколько каждое число встречается в массиве и вывести информацию на экран.
  6. Выяснить на каких позициях встречается каждое число в массиве и вывести информацию на экран.

Как с этим работать

В С++ встроена библиотека STL, которое содержит в себе некоторые типовые объекты и функции для выполнения часто повторящихся действий. Один из очень удобных объектов это динамический массив (или вектор). Работать с ним очень просто:

#include <iostream>
#include <vector> // подключили динамический массив

using namespace std;

int main()
{
    vector<int> A; // обявили динамический массив из элементов типа int
    // vector<float> B; // если нужно float
    // vector<string> C; // или string
    // vector<vector<int> > D; // можно даже так, динамический массив динамичиских маасивов, обратите внимание на пробел мужде закрывающими треугольными скобками

    cout << "Размер массива A: " << A.size() << endl; // выведет 0

    A.push_back(112); // добавили элемент

    cout << "Размер массива A: " << A.size() << endl; // выведет 1
    cout << "Элемент 0 массива A: " << A[0] << endl; // выведет 112

     // добавили три элемента
    A.push_back(113);
    A.push_back(114);
    A.push_back(115);

    cout << "Размер массива A: " << A.size() << endl; // выведет  4

    // чтобы обойти все элементы можно использовать следующий подход
    // то есть по сути все также как и раньше, только размер хранится прямо в массиве
    for (int i=0;i<A.size();++i) {
        cout << A[i] << " ";
    }
    cout << endl;

    // для удаления элементов используются более сложные методы, например
    A.erase(A.begin() + 1); // удалить второй элемент

    for (int i=0;i<A.size();++i) {
        cout << A[i] << " ";
    }
    cout << endl;

    // можно удалить все элементы
    A.clear();
    cout << "Размер массива A: " << A.size() << endl; // выведет 0

    return 0;
}

еще, одна очень удобная структура это ассоциативный массив или map, поволяет сопоставлять ключу некоторое значение.

#include <iostream>
#include <map> // подключили ассоциативный массив

using namespace std;

int main()
{
    map<string, int> products; // обяъвляем ассоциативный массив, сопоставляем слову чисдо

    products["яблоки"] = 10;
    products["мандарины"] = 50;
    products["ананас"] = 1;

    products["яблоки"] += 5; // добавили пять яблок

    cout << "На складе: " << products["яблоки"] << " яблок" << endl; // выведет "На складе 15 яблок"
    
    // вывести все элементы ассоциативного массива немного хитро
    // сначала надо объявить так называемый итератор
    map<string, int>::iterator iter;
    // затем сделать цикл от begin до end
    for(iter = products.begin(); iter != products.end(); ++iter )
    {
        // ну и выводить, ключ лежит iter->first
        // значение в iter->second
        cout << iter->first << ": " << iter->second << endl;
    }

    return 0;
}

хотя, можно и проще, для этого надо активировать в компиляторе (Settings/Compiler) режим современного C++

и тогда цикл можно писать так:

for (auto item : products) {
    cout << item.first << ": " << item.second << endl;
}

помимо популярных контейнеров для хранения данных есть еще библиотчека которая хранит методы для работы с данными, такие как поиск наибольшего/наименьшего элемента и сортировка.

#include <iostream>
#include <algorithm> // подключили библиотечку с алгоритмами
#include <vector>

using namespace std;

int main()
{
    vector<int> A {5,7,3,1}; // объявили динамический массив с фиксированными значениями

    // проверка на существование элемента, в динамическом массиве
    bool elementExists = find(A.begin(), A.end(), 3) != A.end(); // да-да, именно не равно
    cout << elementExists << endl;

    // сортировка
    sort(A.begin(), A.end());
    // с последующим выводом
    for (auto i : A) {
        cout << i << " ";
    }
    cout << endl;

    // обратная сортировка
    reverse(A.begin(), A.end());
    for (auto i : A) {
        cout << i << " ";
    }
    cout << endl;

    // поиск максимального элемента
    // звездочка нужна затем что, возвращаемое функцией значение это указатель на память
    // чтобы указатель на память преобразовать в значение которое лижит по адресу
    // надо добавить звездочук
    int maxValue = *max_element(A.begin(), A.end()); 
    cout << "max value is: " << maxValue << endl;

    // поиск минимального элемента
    int minValue = *min_element(A.begin(), A.end());
    cout << "min value is: " << minValue << endl;


    return 0;
}

кстати те же методы можно применять и к обыкновенным массивам, правда запись становится немного хитрее

#include <iostream>
#include <algorithm> // подключили библиотечку с алгоритмами
#include <vector>

using namespace std;

int main()
{
    int A[] {5,7,3,1}; // объявили динамический массив с фиксированными значениями

    int maxElement = *max_element(&A[0], &A[4]); // знак & перед A, нужен чтобы получить адрес в памяти нулевого или 4го элемента
    cout << maxElement << endl;

    sort(&A[0], &A[4]);
    for (auto i : A) {
        cout << i << " ";
    }

    return 0;
}