Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Объявление и определение функции

Семинар 6. Работа с функциями

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

Объявление и определение функции

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

тип имя_функции ( [ тип имя_параметра, тип имя_параметра, … ] );

или

тип имя_функции ( [ тип_параметра, тип_параметра, … ] );

Чтобы определить функцию, нужно повторить ее заголовок с указанием имен параметров, а затем в фигурных скобках задать необходимые описания и операторы (тело функции). Если определение функции приведено до ее первого использования, то функцию можно не объявлять.

тип имя_функции ( [ тип имя_параметра, тип имя_параметра, … ] )

{

//тело функции

}

Тип возвращаемого значения может быть любым кроме массива и функции. Если указан тип void, то функция не возвращает значения. Если void указан внутри круглых скобок, то функция не имеет параметров.

Оператор return

Для выхода из функции и указания возвращаемого значения используется оператор return:

return [выражение];

Функция может содержать несколько операторов return, если этого требует алгоритм. Для функций типа void выражение отсутствует. Оператор return в этом случае можно опускать, если он стоит перед закрывающей фигурной скобкой. Также можно опускать оператор return для функции main.

Параметры функции

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

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

Существует три способа передачи параметров в функцию: «по значению», «по указателю», «по ссылке».

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

Если параметр передается в функцию по указателю, то функция получает адрес этого параметра. Чтобы получить доступ к значению переменной в теле функции нужно применить операцию разыменования (*). В данном случае никакой копии не делается, и функция работает непосредственно с фактической переменной.

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

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

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

Параметром функции также может быть указатель на функцию (см. пример 6.2).

 

Пример 6.1. Различные способы передачи параметров в функцию.

Функция Param имеет 3 параметра. Первый параметр передается «по значению», второй – «по указателю», третий – «по ссылке». В первом случае формальный параметр объявляется как обычная переменная, во втором – как переменная указатель, в третьем – используется символ «&», который как раз и указывает, что это ссылка.

При обращении к функции фактические значения первого и третьего параметров – это просто переменные (в функцию передается копия x и сама переменная z), фактическое значение второго параметра – это адрес переменной y (для получения адреса используется операция &). В теле функции всем трем переменным присваивается значение ноль. Для доступа к значению, хранящемуся по адресу, переданному во втором параметре, используется операция разыменования (*).

После выполнения функции мы увидим, что значение x не изменилось (ведь функция работала с локальной переменной a, значение которой равно x), а y и z действительно стали равны 0.

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

Пример 6.2. Имя функции в качестве параметра.

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

В теле функции f3 показаны два способа вызова функции-параметра (*f)(a) и f(a) (второй способ выглядит естественнее), а в Prim6_2 – 2 способа указания фактического параметра-функции (в одном случае используется операция &, а в другом – нет).

 

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

void f(int arg1= 0, int arg2 = 1000);

void f(int = 0, int = 1000);

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

Пример вызова функции: f(), f(22), f(3, 9). Нельзя задать только второй аргумент, а для первого использовать значение по умолчанию.

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

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

Пример 6.3. Использование перегруженных функций.

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

Шаблоны функций

Шаблон (template) – средство программирования, которое позволяет создавать функции и классы, в которых тип задается в качестве параметра.

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

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

В простейшем случае функция-шаблон определяется так:

template < typename тип_данных>

тип_функции имя_функции (параметры) {

/* тело функции */}

Тип_данных – это имя фиктивного типа. Компилятор автоматически заменит его именем реального типа данных при создании конкретной версии функции. Вместо слова typename может использоваться class.

Параметры шаблона указываются в угловых скобках через запятую. Их может быть несколько. Параметр может быть не только типом, но и просто переменной:

template < typename T1, typename T2, int i> void F() {…}

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

F< int, double, 10> ();

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

Пример 6.4. Использование шаблонов функций.

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

Задания для самостоятельной работы

1. Напишите функцию, которая для заданного радиуса r вычисляет площадь круга и длину окружности.

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

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

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

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

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

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

 

<== предыдущая лекция | следующая лекция ==>
Пример 5.5. | Структуры




© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.