Предлагается структурировать программу вторым способом

Лабораторная работа № 8

 

Функции пользователя

 

Описание функций

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

Программа на языке Си состоит, по крайней мере, из одной функции – функции main. С нее всегда начинается выполнение программы. Встретив имя функции в выражении, программа вызовет эту функцию, т.е. передаст управление на ее начало, и начнет выполнять операторы. Достигнув конца функции в виде оператора return – выхода из функции, управление вернется в ту точку, откуда функция была вызвана, подставив вместо нее вычисленный результат.

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

Тип_результата имя_функции (список_формальных_параметров с указанием их типов)

{

определения_объектов;

исполняемые_операторы;

return <выражение>;

}

float dlina_otrezka (float x1, float y1, float x2, float y2 )

{float result;

result = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);

return sqrt(result);

}

Введение функции в текст программы может быть организовано одним из двух способов:

1. после описания директив процессора дается описание функций пользователя, а затем идет описание главной функции;

2. после описания директив процессора дается описание прототипов функций пользователя, после чего идет описание главной функции main () , а после нее ниже идет последовательное описание функций пользователя. Прототип в общем виде выглядит так:

тип_результата имя_функции (список типов параметров);

Список параметров может быть как с именами параметров, так и без них.

Замечания:

1. Вложенные описания функций в языке не используются.

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

3.   Принципиально важным оператором тела функции является оператор   возврата из функции в точку ее вызова:

return выражение;

или return;

Выражение в операторе возврата задает возвращаемое функцией значение.

Для функции типа void, не возвращающей никакого значения, выражение в операторе return отсутствует. В теле такой функции оператор return может вообще отсутствовать. В этом случае компилятор предполагает, что оператор return находится в самом конце тела функции. Применение оператора return допустимо и в функции main(). Если программист явно не поместил в функцию main() оператор return, то компилятор поместит его в конце текста функции main(). В отличие от "неглавных" функций, откуда возврат выполняется в вызывающую функцию, выполнение оператора return; или return выражение; в функции main() приводит к завершению программы. Управление при таком выходе передается вызывающей программе, например операционной системе, которая может анализировать значение выражения, использованного в операторе возврата.

Вызов функции

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

Указание: необходимо разработать функцию пользователя для вычисления длины отрезка, заданного координатами концов.

Пример 1.

Предлагается структурировать программу первым способом

Пример 2.

Предлагается структурировать программу вторым способом

 

Аргументы функции x1, x2, y1 и y2 называются формальными параметрами. Данные параметры определены (видны) исключительно в теле функции (т.е. к ним можно обращаться только внутри фигурных скобок). При написании определения функции программа не знает их значения. При вызове функции вместо них подставляются фактические параметры – значения, с которыми функция вызывается. В нашем примере это использование обращения к функции в операторе присваивания для вычисления длин сторон треугольника

AB=dlina_otrezka(Ax, Ay, Bx, By);

AC=dlina_otrezka(Ax, Ay, Cx, Cy);

BC=dlina_otrezka(Cx, Cy, Bx, By);

В нашем случае Ax, Ay, Bx, By, Cx, Cy - фактические параметры – значения. В каждый конкретный момент обращения к функции значения фактических параметров присваиваются формальным параметрам, для которых исполняется алгоритм вычисления значения функции, возвращаемого оператором return

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

Значение переменной result вычисляется в соответствии с математической моделью, использованной для данного алгоритма.

Оператор return завершает выполнение функции и возвращает выражение, записанное после ключевого слова return, в качестве выходного значения. После завершения выполнения функции она уничтожается – ее имя становится неизвестным, и память, занимаемая этой переменной, освобождается.

Зачем использовать функции

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

Дело в том, что, если вы не используете функции, то программа становится менее мобильной. Например, конкретная ситуация. Вы работаете над проектом и уже написали несколько тысяч строк кода, затем решили изменить вывод сообщения с «Привет!» на «Привет дорогой читатель!». Для этого вам придется найти все строки, в которых происходит вывод сообщения и изменить их все.

А если бы вы использовали функцию, которая выводила сообщение «Привет!», то тогда бы вам пришлось только найти эту функцию и изменить ее!

Перегрузка функций

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

Все дело в том, что у каждой функции есть свое полное имя(или по-другому сигнатура). Параметры функции — это вся информация о функции. В эту информацию входят:

· Имя функции.

· Число аргументов функции.

· Типы аргументов.

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

Перегрузка функций — это создание функций с одинаковыми именами, но с разными сигнатурами (полными именами).

В примере ниже все функции разные, хотя и имена у них одинаковые:

1 2 3 4 5 6 7 8 9 1 1 1 int func(int a) { // выполнение функции номер 1 } double func() { // выполнение функции номер 2 } int func(double b, double h) { // выполнение функции номер 3 } long long func(int n, int c, int g) { // выполнение функции номер 4 }

Распространенной ошибкой является мнение, что тип возвращаемого значения функции входит в полное имя функции.

В примере ниже три функции имеют одинаковые типы возвращаемого значения (но полные имена у них совершенно идентичны), и поэтому компилятор начнет ругаться на нас (почему мы создали одинаковые функции!).

1 2 3 4 5 6 7 8 9 int func() { } double func() { //ошибка: функция с таким именем уже существует } long long func() { //ошибка: функция с таким именем уже существует }

Заголовочные файлы

 

Файлы .cpp не являются единственными файлами в проектах. Есть ещё один тип файлов — заголовочные файлы (или ещё «заголовки»), которые имеют расширение .h. Целью заголовочных файлов является удобное хранение набора объявлений объектов для их последующего использования в других программах.

Написать свой собственный заголовочный файл не так уж и сложно. Заголовочные файлы состоят из двух частей:

директивы препроцессора, в частности, header guards, которые предотвращают вызов заголовочного файла больше одного раза с одного и того же файла;

содержимое заголовочного файла: набор объявлений.

Все ваши заголовочные файлы (которые вы написали самостоятельно) должны иметь расширение .h.

add.h:

  // Начинаем с директив препроцессора. ADD_H – это произвольное уникальное имя (обычно используется имя заголовочного файла) #ifndef ADD_H #define ADD_H // А это уже содержимое заголовочного файла int add(int x, int y); // прототип функции add() (не забывайте точку с запятой в конце!) // Заканчиваем директивой препроцессора #endif

Чтобы использовать этот файл в main.cpp, вам сначала нужно будет подключить его к проекту. main.cpp, в котором мы подключаем add.h:

  #include <iostream> #include "add.h"   int main() { std::cout << "The sum of 3 and 4 is " << add(3, 4) << std::endl; return 0; }

add.cpp:

  int add(int x, int y) { return x + y; }

Когда компилятор встречает #include "add.h", он копирует всё содержимое add.h в текущий файл. Таким образом, мы получаем предварительное объявление функции add().

Примечание: При подключение заголовочного файла, всё его содержимое вставляется сразу же после строчки #include ....

Если вы получили ошибку от компилятора, что add.h не найден, то убедитесь, что имя вашего файла точно «add.h». Вполне возможно, что вы могли сделать опечатку, например: просто «add» (без «.h») или «add.h.txt» или «add.hpp».

Если вы получите ошибку от линкера, что функция аdd() не определена, то убедитесь, что вы корректно подключили add.cpp к вашему проекту (и к компиляции тоже)!

 


Задания для выполнения

1. Реализуйте представленные в лабораторной работе примеры.

2. Доработайте пример так, чтобы программа проверял существование треугольника.

3. Вычислите значение выражения c=max(a,b)+min(a,b). Нахождение значений максимума и минимума оформите с помощью функций.

4. Напишите программу вычисления суммы двух целых чисел, трех целых чисел двух вещественных чисел, используя перегрузку функций.

5. Написать функцию, которая определяет количество разрядов введенного целого числа.

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

7. Найти наибольший общий делитель (НОД) для пары чисел.

8. Составьте программу нахождения всех совершенных чисел, расположенных на отрезке [a,b], где a и b – натуральные числа. Для решения задачи разработайте функцию определения совершенного числа.

9. Составьте программу нахождения всех простых чисел, расположенных на отрезке [a,b], где a и b – натуральные числа. Для решения задачи разработайте функцию определения простого числа.

10. Составить программу разложения данного натурального числа на простые множители. Например, 200 = 23 • 52.

11. Два натуральных числа называются «дружественными», если каждое из них равно сумме всех делителей (кроме его самого) другого (например, числа 220 и 284). Найти все пары «дружественных» чисел, которые не больше данного числа N.

12. Натуральное число, в записи которого n цифр, называется числом Армстронга, если сумма его цифр, возведенная в степень n, равна самому числу. Найти все числа Армстронга от 1 до k.

13. Найти все простые натуральные числа, не превосходящие n, двоичная запись которых представляет собой палиндром, т. е. читается одинаково слева направо и справа налево.

14. Составить программу для нахождения чисел из интервала [М, N], имеющих наибольшее количество делителей.

15. Индивидуальное задание. Вычислите сумму ряда, используя функции пользователя: (n!=1*2*3*…*n)

Задание
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.

 


Дата добавления: 2021-07-19; просмотров: 126; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!