№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–999. Вывести его описание вида «четное двузначное число», «нечетное трехзначное число» и т. д.
- Даны уравнения двух прямых и . Определить, пересекаются ли эти прямые, совпадают или параллельны.
Как это делать
Условный оператора это контрукция 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 до 10 выдаст название числа.
- Единицы длины пронумерованы следующим образом: 1 — дециметр, 2 — километр, 3 — метр, 4 — миллиметр, 5 — сантиметр. Дан номер единицы длины (целое число в диапазоне 1–5) и длина отрезка в этих единицах (вещественное число). Найти длину отрезка в метрах.
- Элементы окружности пронумерованы следующим образом: 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
Задания
- Дан массив . Запросить у пользователя элементы массива и найти сумму квадратов этих чисел.
- Дан массив . Запросить у пользователя элементы массива и найти произведение этих чисел.
- Найти n-факторил, значение n запрашивать у пользователя
- Дан массив . Запросить у пользователя элементы массива и вывести на экран нечетные числа.
- Дан массив , числа 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.
Разберем пошагово как сработает код с циклом
- Сначала создается переменная i, и ей присваивается значение 0
- Проверятся условие
i<=4
? Так как i равно 0, то проверяется0<=4
? Так как это условие верно переходим к телу цикла - В теле цикла вместо i подставляется 0, и вызывается команда
cin >> numbers[0]
. То есть просто запрос у пользователя нулевого элемента - Так как больше команд в теле цикла нет, то вызывется выражение
++i
, которое увеличивает значение i на единицу, то есть i теперь равно 1. - Снова проверяется
i<=4
? Так как i равно 1, то проверяется1<=4
? Так как это условие верно переходим к телу цикла - В теле цикла вместо i подставляется 1, и вызывается команда
cin >> numbers[1]
. То есть просто запрос у пользователя первого элемента - Так как больше команд в теле цикла нет, то вызывется выражение
++i
, которое увеличивает значение i на единицу, то есть i теперь равно 2. - Снова проверяется
i<=4
? Так как i равно 2, то проверяется2<=4
? Так как это условие верно переходим к телу цикла - В теле цикла вместо i подставляется 2, и вызывается команда
cin >> numbers[2]
. То есть просто запрос у пользователя второго элемента - Так как больше команд в теле цикла нет, то вызывется выражение
++i
, которое увеличивает значение i на единицу, то есть i теперь равно 3. - Снова проверяется
i<=4
? Так как i равно 3, то проверяется3<=4
? Так как это условие верно переходим к телу цикла - В теле цикла вместо i подставляется 3, и вызывается команда
cin >> numbers[3]
. То есть просто запрос у пользователя третьего элемента - Так как больше команд в теле цикла нет, то вызывется выражение
++i
, которое увеличивает значение i на единицу, то есть i теперь равно 4. - Снова проверяется
i<=4
? Так как i равно 4, то проверяется4<=4
? Так как это условие верно переходим к телу цикла - В теле цикла вместо i подставляется 4, и вызывается команда
cin >> numbers[4]
. То есть просто запрос у пользователя четвертого элемента - Так как больше команд в теле цикла нет, то вызывется выражение
++i
, которое увеличивает значение i на единицу, то есть i теперь равно 5. - Снова проверяется
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 Работа с матрицами
Задачи
- Дана матрица 3x3, запросить значения у пользователя и найти определитель.
- Дана матрица произвольного размера, запросить у пользвателя ее размеры, рассчитать транспонированую матрицу, и вывести ее на экран
- Даны две матрицы A и B одинакового размера, найти матрицу A+B, и вывести ее на экран
- Дана квадратная матрица порядка 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 Функции
Задание
- Дано три массива чисел размерностью 4, найти произведение средних арифметических значений этих массивов. Для расчета среднего арифметического написать функцию.
- Дано три числа найти сумму факториалов . Для расчета факториала написать функцию
- Дано три числа найти сумму сумм первых a(b,c) членов арифметической прогрессий . Для расчета арифметической прогрессии написать функцию
- Дано три точки в пространстве, рассчитать периметр треугольника лежащего на этих точках. Для рассчета длины отрезка написать функцию.
Как это делать
Использование функций это хороший способ более грамотно организовать код. В функцию часто выносят какие-то повторяющиеся действия.
В любой программе по умолчанию уже есть одна функцию именуемая 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 и чуток современного С++
Задания
- Доработать игру в угадайку, в случае угадывания числа, выводить все числа которые вводил пользователь
- Запросить у пользователя произвольное количество чисел (считать что пользователь больше не хочет вводить числа если он ввел 0). Вывести на экран сначала положительные числа, а потом отрицательные.
- Найти среднее арифметическое значение максимального и минимального элементов в массиве
- Найти максимальное среди минимальных значений матрицы. Использовать библиотчечку algorithm
- Подсчитать сколько каждое число встречается в массиве и вывести информацию на экран.
- Выяснить на каких позициях встречается каждое число в массиве и вывести информацию на экран.
Как с этим работать
В С++ встроена библиотека 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;
}