Содержание:
C++ аргументы по ссылке
Еще о цикле for
В цикле for
можно использовать несколько счетчиков: область инициализации счетчика, так же как и область изменения счетчика может состоять из нескольких операторов, разделенных запятой «,
»
int a = 0, b = 0; for (a = 1, b = 8; a < b; ++a, --b) { // empty body } cout << a << " " << b << endl; // вывод: 5 4 |
Ссылки
Ссылка — это не объект, это другое имя объекта; ссылки не занимают место в памяти:
Пример 1:
int i = 5; int &pi = i; // ссылка на i pi = 3; cout << i; // i == 3 |
Пример 2:
void double_numb(int &numb) { numb *= numb; // 'numb' - это тот же 'x' в функции main() } void main(){ int x = 2; double_numb(x); cout << x << '\n'; system("pause"); } |
Пример 3. Передача аргумента по ссылке:
void calcSquareAndPerimeter(double a, double b, double &S, double &P) { S = a * b; P = 2 * (a + b); } int main() { double SS = 0.0, PP = 0.0; calcSquareAndPerimeter(3.0, 4.0, SS, PP); cout << "Perimeter: " << PP << ", Square: " << SS << "\n"; } |
Пример 4. Передача аргумента по ссылке:
int a = 5; int& ra = a; ra = 3; void swap( int & a , int & b ) // Передача по ссылке { auto v = a; a = b; b = v; } int main() { int c, d; swap (c, d); } |
Лабораторные работы
- Создайте приложение с именем
Lesson_3
. Все задания и лабораторные работы должны выполняться в этом приложении. - Это означает, что все задания должны размещаться в одном и том же заголовочном и главном файле. Необходимо размещать комментарии с номером задания и объяснением того, что нужно сделать в нем.
- Каждая задача должна выполняться с использованием пользовательских функций. Например, если задача состоит в том, чтобы найти сумму последовательности из 5 введенных чисел, вы должны создать функцию в файле
.cpp
для выполнения этой задачи: - Старайтесь передавать аргументы функций по ссылке (в тех задачах, где это необходимо).
header.h:
1 2 3 4 5 6 | #ifndef HEADER_H #define HEADER_H // Задание 1 // функция расчета суммы 5 введенных чисел int sumSeq(); #endif |
imp.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <iostream> #include "header.h" using namespace std; // функция расчета суммы 5 введенных чисел int sumSeq() { cout << "enter a sequence"<<endl; int numb; int sum = 0; for (int i = 0; i < 5; i++) { cin >> numb; sum += numb; } return sum; } |
main.cpp:
1 2 3 4 5 6 7 8 9 10 11 | #include "header.h" #include <iostream> using namespace std; void main(){ // задание # 1 // Создать функцию расчета суммы 5 введенных чисел int result = sumSeq(); cout << "задание 1" << endl; cout << result; system("pause"); } |
Для того чтобы результат изменения значений формальных параметров был заметен в точке их вызова, необходимо использовать передачу параметров по ссылке.
Рассмотрим простой пример:
Описать две функции для обмена значениями двух переменных, соответственно, целого и вещественного типа.
* Я. М. Демяненко, М. И. Чердынцева «Методы процедурного программирования в с++» учебное пособие, Ростов-на-дону, 2014, стр. 18
Выполнение:
- Создайте главный и заголовочный файлы. Подключите необходимые библиотеки и заголовочный файл.
- В код заголовочного файла добавьте описание и реализацию двух функций с одинаковым названием — my_swap(): для обмена значений переменных целого типа и для обмена значений переменных вещественного типа:
- Объявление двух функций с одинаковыми именами означает, что имеет место перегрузка имени функции.
- Перегрузка функции — возможность определить несколько функций с одним и тем же именем.
- Перегруженные функции обязательно должны иметь разные сигнатуры, т. е. должны отличаться своими списками спецификации параметров.
- В код главного файла в тело функции main() добавьте описание и ввод необходимых переменных, а также вызов функций:
- В операторе вызова функции my_swap(k,m) в качестве фактических параметров используются две целые переменные k и m. В таком случае компилятор вызовет ту версию перегруженной функции, у которой параметрами являются целые переменные.
- Оператор вызова функции my_swap(a,b) использует два фактических параметра вещественного типа. Для него будет осуществлен вызов функции с двумя вещественными параметрами.
// объявление функций void my_swap(double &a, double &b); void my_swap(int &a, int &b); // определение (реализация) функций void my_swap(double &a, double &b) { double r = a; a=b; b=r; } void my_swap(int &a, int &b) { int r=a; a=b; b=r; } |
В объявлении и определении функций используется передача параметров по ссылке, о чем указывает символ
&
. Ссылочные переменные позволяют сохранять результат изменения значений формальных параметров таким образом, чтобы он был «виден» в точке их вызова.
int main() { int k,m; cout<<"введите два целочисленных значения:"; cin>>k>>m; cout<<k<<" "<<m<<endl; my_swap(k, m); cout<<k<<" "<<m<<endl; double a,b; cout<<"введите два вещественных значения:"; cin>>a>>b; cout<<a<<" "<<b<<endl; my_swap(a,b); cout<<a<<" "<<b<<endl; system("pause"); return 0; } |
Реализовать перегруженные функции для нахождения максимального из нескольких значений, возможно, разных типов.
Указания:
* Я. М. Демяненко, М. И. Чердынцева «Методы процедурного программирования в с++» учебное пособие, Ростов-на-дону, 2014, стр. 25
Выполнение:
- Создайте главный и заголовочный файлы. Подключите необходимые библиотеки и заголовочный файл.
- В код заголовочного файла добавьте описание и реализацию трех функций с одинаковым названием — max(), но с разным количеством параметров и их типом (объявление функций добавьте самостоятельно, пользуясь кодом их определения):
- Вызовы функций порой приводят к снижению производительности программы. В C++ для минимизации такого эффекта предусмотрен механизм встраиваемых (inline) функций, которые иногда еще называют подставляемыми.
- Спецификация inline перед указанием типа результата в объявлении предлагает компилятору сгенерировать копию кода функции в соответствующем месте, чтобы избежать вызова этой функции. В результате получается множество копий кода функции, вставленных в программу, вместо единственного экземпляра кода, которому передается управление при каждом вызове функции.
inline int max(const int a, const int b) { return a>b?a:b; } inline int max(const int a, const int b, const int c) { int d=a>b?a:b; return d>c?d:c; } inline double max(const double a, const double b) { return a>b?a:b; } |
- Аргументы по умолчанию — значения, которые автоматически подставляются компилятором при вызове функции, если аргумент не был указан при вызове.
- Аргументы по умолчанию могут быть расположены только в конце списка формальных параметров.
int max(int a, int b = 1);
Создать проект с функцией сортировки трех значений с возможностью задать направление сортировки. Реализовать тестирующую программу.
Реализовать перегруженные функции для сортировки нескольких значений (двух, четырех), возможно, разных типов.
Подробно:
Создать функцию:
void sort ( double &a, double &b, double &c, bool asc = 0); |
которая выполняет сортировку трех значений с возможностью задать направление сортировки.
Параметры функции:
a, b, c – значения для сортировки.
asc — флаг направления сортировки:
— false — по убыванию (по умолчанию),
— true — по возрастанию.
Возвращаемое значение: нет
Результат:
a, b, c отсортированные в соответствии со значением asc.
Дано целое число. Определить количество и сумму цифр в десятичной записи этого числа. Выдать само число и число, получающееся из него при вычеркивании первой и последней цифр.
Указания:
Оформить в виде функций каждое из действий:
int count_dig(int a); //параметр передается по значению |
int sum_dig(int a); //параметр передается по значению |
void del_last_dig(int& a); //параметр передается по ссылке void del_first_dig(int& a); //параметр передается по ссылке |
* Я. М. Демяненко, М. И. Чердынцева «Методы процедурного программирования в с++» учебное пособие, Ростов-на-дону, 2014, стр. 29
Выполнить: Создайте функцию для вывода последовательности: -3 0 3 6 9 12 15 18 21 24
и суммы ее элементов. Выполните задачу с помощью цикла FOR
. Итератор цикла с шагом, равным 3.
Указание 1: Чтобы сделать шаг равным 3, используйте синтаксис:
for ([initializers]; [condition]; [iterator])
вместо итератора у вас будет переменная counter += 3
Указание 2: Сигнатура функции должна быть void printSeq(int a, int b, int & sum)
, где a = -3 и b = 24.
Указание 3: Не забудьте использовать оператор assert
, чтобы проверить, больше ли b, чем a.
#include <cassert> |
Примерный вывод:
Последовательность: -3 0 3 6 9 12 15 18 21 24 сумма: 105
[Solution and Project name: Lesson_3
файлы: header.h
, imp.cpp
, main.cpp
]
// задание 4
L3Task1header.h
, L3Task1imp.cpp
, L3Task1main.cpp
Выполнить: Вводится 10 целых чисел. Создайте функцию (findPosNeg
) для вывода количества положительных и отрицательных значений среди них.
Указание 1: Создайте цикл for
для ввода чисел. Внутри цикла проверьте каждое число, является ли оно положительным или отрицательным. Используйте два счетчика.
Указание 2: сигнатура функции:
void findPosNeg(int & pos, int & neg){ //TODO } |
Примерный вывод:
введите 10 чисел: 1 -5 -12 2 3 9 -1 9 5 -8 counter_positive = 6, counter_negative = 4
[Solution and Project name: Lesson_3
]
// Задание 5
Выполнить: Создайте функцию для вычисления суммы следующей последовательности: 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 (числа НЕ вводятся, они должны быть созданы с помощью цикла). Границы последовательности должны быть параметрами функции, сумма — также параметр функции, передаваемый по ссылке.
Примерный вывод:
последовательность: 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 sum = 100
[Solution and Project name: Lesson_3
]
// Задание 6
Выполнить: Для каждого x
, изменяющегося в интервале [x1;x2] (значения x1
и x2
вводятся), вычислите значение функции z(x,y) = xy
. Переменная y
изменяется в интервале [y1;y2] (значения y1
и y2
вводятся). Вы должны создать функцию.
Указание 1: Создайте два цикла for
(вложенный цикл): один цикл внутри другого. Переменная x
должна быть изменена во внешнем цикле; переменная y
должна быть изменена во внутреннем цикле.
Указание 2: Чтобы вывести степень числа, используйте функцию pow
директиву #include<cmath>
:
f = pow(base number, exponent); |
Указание 3: Не забудьте использовать оператор assert
для проверки значений (x2>x1
и y2>y1
).
Примерный вывод:
введите x1 и x2: >>>2 >>>8 введите y1 и y2: >>>2 >>>4 z(x,y) = 2^2 = 4 z(x,y) = 2^3 = 8 z(x,y) = 2^4 = 16 z(x,y) = 3^2 = 9 z(x,y) = 3^3 = 27 z(x,y) = 3^4 = 81 z(x,y) = 4^2 = 16 z(x,y) = 4^3 = 64 z(x,y) = 4^4 = 256 z(x,y) = 5^2 = 25 z(x,y) = 5^3 = 125 z(x,y) = 5^4 = 625 ... и т.д.
[Solution and Project name: Lesson_3
]
// task 7
Выполнить: Создайте функцию для вывода последовательности 15 12 9 6 3 0
(от 15 до 0 с шагом = -3) и суммы четных элементов последовательности. Используйте цикл while
.
Указание: Сигнатура функции должна быть:
void printSeqTask5(int a, int b, int & sum){ … } |
Где a = 15
, а b = 0
Примерный вывод:
результат: 15 12 9 6 3 0 сумма четных = 18
[Solution and Project name: Lesson_3
]
// задание 8
Выполнить: Создайте функцию для вычисления произведения 2-значных четных чисел в интервале [10;20] (10 * 12 * 14 * 16 * 18 * 20
). Вы должны выполнить задачу, используя цикл while
.
Указание 1: Для вычисления произведения следует использовать переменную с именем product
. Не забудьте инициализировать переменную product
значением 1.
Указание 2: Сигнатура функции:
void findMult(int a, int b, int & prod){ … } |
где a = 10
и b = 20
Примерный вывод:
10 * 12 * 14 * 16 * 18 * 20 произведение: 9676800
[Solution and Project name: Lesson_3
]
// задание 9
Выполнить: Вводятся два двузначных целых числа. Создайте функцию BitwiseSum()
, которая вычисляет их побитовую сумму по модулю 10. Например, побитовая сумма чисел 34 и 59 — это число 83 (3 + 5 = 8; 4 + 9 = 13; 13%10 = 3).
Указание: Функция BitwiseSum()
должна принимать три аргумента по ссылке (два числа и sum
).
Примерный вывод:
Введите два двухзначных числа: >>> 34 >>> 59 Побитовая сумма 34 и 59 = 83
[Solution and Project name: Lesson_3
]
// задание 10
Выполнить: Задается последовательность целых чисел (вводится). Последний элемент последовательности равен 0
. Вычислите сложение всех положительных элементов этой последовательности и найдите количество ее отрицательных элементов. Необходимо использовать цикл While
.
Указание 1: В задаче вы должны использовать бесконечный цикл с выходом из середины:
while (true) { // TODO something if (num == 0) break; // TODO something } |
Указание 2: Чтобы вернуть значения из функции, вы должны использовать параметры по ссылке (&
):
void sumPosCountNeg(int & pos_sum, int & neg) {} |
Примерный вывод:
Введите последовательность, закончите ввод 0: >>> 3 5 -1 2 -3 0 Сумма положительных: 10 Кол-во отрицательных: 2
[Solution and Project name: Lesson_3
]
// задание 11
Выполнить: Задается последовательность целых чисел (вводится). Последний элемент последовательности равен 0
. Найдите минимальный и максимальный элементы. Необходимо использовать цикл While
.
Указание 1: В задаче вы должны использовать бесконечный цикл с выходом из середины:
while (true) { // TODO something if (num == 0) break; // TODO something // } |
Указание 2: Чтобы вернуть значения из функции, вы должны использовать параметры по ссылке (&
):
void minMax(int &min, int &max) {} |
Указание 3: Следует использовать начальные значения INT32_MAX
и INT32_MIN
для переменных min
и max
.
Примерный вывод:
Введите последовательность, закончите ввод 0: >>> 3 5 -1 2 -3 0 minimum : -3 maximum : 5
[Solution and Project name: Lesson_3
]
// задание 12
EXTRA TASKS
Выполнить: Задается целое число. Найдите количество его цифр и их сумму.
Указание: Сигнатура функции:
void digitsCountAndSum (int n, int& count, int& sum) |
Примерный вывод:
Введите число: >>> 12345 Кол-во цифр = 5, сумма = 15
[Solution and Project name: Lesson_3
, files: L3ExTask1header.h
, L3ExTask1main.cpp
, L3ExTask1imp.cpp
]
Выполнить: Задано целое число N
и набор из N
положительных вещественных чисел. Вычислите сумму всех целых частей чисел последовательности, а также сумму всех дробных частей чисел последовательности.
Примерный вывод:
Введите N: >>> 4 12,4 11,7 8,5 1,1 Сумма целых частей: 32 Сумма дробных частей: 1.7
[Solution and Project name: Lesson_3
, files: L3ExTask2header.h
, L3ExTask2main.cpp
, L3ExTask2imp.cpp
]
Домашнее задание
Выполнить: Вводятся 10 действительных чисел. Создайте функцию для вывода произведения введенных чисел.
Указание 1: Создайте цикл for
для ввода чисел. Чтобы вычислить умножение, используйте переменную с именем product
.
Указание 2: Не забудьте инициализировать переменную product
значением типа double
.
double product = 1.0;
Примерный вывод:
1,1 2,4 5,1 7,2 6,4 8,1 6,7 3,2 3,3 2,4 product = 853338,921998746
[Solution and Project name: Lesson_3
, files: L3HomeTask1header.h
, L3HomeTask1main.cpp
, L3HomeTask1imp.cpp
]
Выполнить: Для каждого x
, изменяющегося в интервале [30;33], вычислите значение функции z(x,y) = x - y
. Переменная y
изменяется в интервале [1;5]. Вы должны создать функцию.
Указание: Создайте два цикла for
(вложенный цикл): один цикл внутри другого. Переменная x
должна быть изменена во внешнем цикле; переменная y
должна быть изменена во внутреннем цикле.
Примерный вывод:
z(x,y) = 30-1=29 z(x,y) = 30-2=28 z(x,y) = 30-3=27 z(x,y) = 30-4=26 z(x,y) = 30-5=25 z(x,y) = 31-1=30 ... и т.д.
[Solution and Project name: Lesson_3
, files: L3HomeTask2header.h
, L3HomeTask2main.cpp
, L3HomeTask2imp.cpp
]
Выполнить: Создайте функцию для вывода последовательности 3 5 7 9 ... 21
(от 3 до 21 с шагом = 2) и количества элементов кратных трем.
Указание: Сигнатура функции должна быть void seq(int a, int b, int & counter)
, где a = 3 и b = 21.
Примерный вывод:
3 5 7 9 11 13 15 17 19 21 кратных трем: 4
[Solution and Project name: Lesson_3
, files: L3HomeTask3header.h
, L3HomeTask3main.cpp
, L3HomeTask3imp.cpp
]
Выполнить: Вводятся 5 действительных чисел. Создайте функцию для вычисления суммы введенных чисел. Выполните задачу, используя цикл while
.
Указание: Double
тип должен использоваться для действительных чисел и для переменной суммы:
double sum = 0; double numb;
Please enter 5 numbers and press Enter
1.1 4.2 2.1 9.3 2.5 сумма = 19.2
[Solution and Project name: Lesson_3
, files: L3HomeTask4header.h
, L3HomeTask4main.cpp
, L3HomeTask4imp.cpp
]
Указания: задания следует сохранить в файле с именем задания, и обязательно в коде вставить комментарий с постановкой задачи.
Рекурсия
- rec1: Напишите рекурсивную функцию, которая раскладывает число на простые сомножители.
- rec2: Дано натуральное число N. Требуется получить и вывести на экран количество всех возможных различных способов представления этого числа в виде суммы натуральных чисел (то есть, 1 + 2 и 2 + 1 – это один и тот же способ разложения числа 3). Решите задачу с помощью рекурсивной процедуры.
Пример:
Введите натуральное число: 378 378 = 2*3*3*3*7
Пример:
Введите натуральное число: 4 Количество разложений: 4.