Не зависят от конкретного компьютера Язык Си
![]()
|
Функции Описание функции состоит из заголовка и тела функции. Тело функции представляет собой последовательность описаний и операторов, заключенных в фигурные скобки. Функции В общем случае заголовок функции содержит тип возвращаемого значения и имя функции, за которыми в круглых скобках указывается список передаваемых параметров, разделяемых между собой запятыми. Значение – результат выполнения функции. Параметр – информация, передаваемая в функцию для обработки. Функции Общий вид описания функции: тип имя_функции([тип_1 имя_параметра_1, …, тип_N имя_параметра_N]) // заголовок функции { … // тело функции } Функции Обратите внимание. Функция может быть с параметрами или без параметров. Согласно правилам High Integrity C++ Coding Standard желательно не определять функции с большим количеством параметров (больше 6). Передавать параметры необходимо в том же порядке, в котором они определены в круглых скобках за именем функции. Иначе возникнут ошибки при компиляции либо программа будет работать некорректно. Функции Если вызывающая функция принимает аргументы, то аргументы и тип возвращаемого значения в вызове должны соответствовать параметрам и типу возвращаемого значения в прототипе и в описании функции. Функции Кроме того, в С++ есть: функции, возвращающие значение; функции, не возвращающие значение. Функции, не возвращающие значения, завершив свою работу, не передают результат выполнения вызывающей программе. Описание функции, не возвращающей значение, начинается с пустого типа void. Если void используется для списка параметров функции, это означает, что функция не требует передачи параметров. Функции Синтаксис объявления функции, не возвращающей значение: void имя_функции([тип_параметра, …,]) { … // тело функции } Функции Возврат результата из функции в вызывающую функцию осуществляется оператором return (значение); Функции, возвращающие значение, должны содержать по крайней мере один оператор return, за которым следует возвращаемое значение объявленного типа. Функции Принцип работы оператора. В теле функции вычисляется значение выражения, указанного после оператора return, и преобразуется к типу возвращаемого функцией значения. Любые операторы, следующие в функции за оператором return, игнорируются. Выполнение функции завершается, а вычисленное значение передается в вызывающую функцию. Программа продолжает свою работу с оператора, следующего за оператором вызова данной функции. Функции Синтаксис объявления функции, возвращающей значение: тип имя_функции([тип_параметра, …,]) { … // тело функции return возвращаемое_значение; } Тип возвращаемого значения в заголовке и теле функции должны совпадать. Функции Если в теле функции находится несколько операторов return, то работа функции завершится, если сработает какой-то один из этих операторов. Если функция не имеет возвращаемого значения, то сразу после return ставится точка с запятой: return; Применение оператора return без указания значения вызывает завершение функции и передачу управления в вызывающую функцию. Функции Пример функции с несколькими операторами return. void function(параметры) { if(условие) return; блок операторов; return; } При выполнении условия происходит немедленное завершение функции. Если условие не выполняется – после блока операторов. Функции Если алгоритмически функция не должна иметь возвращаемого значения, но содержит возможность выхода по условию, то, введя возвращаемое значение, можно сделать функцию более информативной. Пример void function(параметры) { if(условие) return 0; блок операторов; return 1; } Функции В данном случае при выполнении условия первый оператор return передает 0 в качестве значения функции, при этом блок операторов и второй оператор return не выполняются. Если условие не выполняется, выполняется блок операторов и второй оператор return в качестве значения функции передает 1. За счет этого вызывающая функция может затем анализировать возвращенное значение. Функции Параметры, указываемые при объявлении прототипа функции и ее описании называются формальными. Параметры (аргументы), указанные в скобках при вызове функции, называются фактическими. Соответствие фактических параметров формальным параметрам устанавливается в том порядке, в котором они были объявлены в вызывающей функции. Функции Рекомендуется, чтобы типы аргументов функции (фактические параметры) соответствовали типам формальных параметров. Значения совместимых типов расширяются автоматически, например, при передаче аргумента типа int параметру типа float, но при этом возможно искажение информации из-за ошибок округления. При передаче аргумента типа float параметру типа int выдается предупреждение (Warning), однако преобразование допустимо, но с явной потерей информации. Функции В случае несовместимых типов фактических и формальных параметров выдается ошибка компиляции «Type mismatch …». Функции Функция может быть описана: до функции main(); после функции main(). В последнем случае необходимо до функции main() объявить прототип функции. Прототип функции – это заголовок функции, который объявляется перед функцией main. Объявление прототипа заканчивается точкой с запятой ; Функции Имена параметров при объявлении прототипа функции являются необязательными, поскольку компилятор игнорирует имена параметров, обращая внимание только на их тип: тип имя_функции([тип_1_параметра_1, …, тип_N_параметра_N]); Т.е. в случае объявления прототипа функции компилятор выполняет проверку на соответствие количества и типов параметров при каждом обращении к функции. Функции Например, прототип функции int factorial(int); идентичен прототипу int factorial(int digit); Информация о функции, содержащаяся в ее прототипе, т.е. количество и тип параметров, называется сигнатурой функции. Способ описания функции после функции main() является более распространенным. Функции Пример программы, в которой объявлена функция нахождения факториала, не возвращающая значение. … void factorial(int digit); // прототип функции factorial int main() { … int n; cout << "Введите число: "; cin >> n; cout << endl; faktorial(n); // вызов функции нахождения факториала … } Функции void faktorial(int digit) // функция factorial { int rezult = 1; for (int i = 1; i <= digit; i++) rezult *= i; cout << digit << "! = " << rezult << endl; } Функция factorial принимает параметр – целое число – и вычисляет его факториал. Результат работы программы: Функции Изменим программу нахождения факториала так, чтобы функция factorial() возвращала полученное значение факториала. … int factorial(int digit); // прототип функции factorial int main() { … int n; cout << "Введите число: "; cin >> n; cout << endl; cout << n << "! = " << faktorial(n) << endl; … } Функции int faktorial(int digit) // функция factorial { int rezult = 1; for (int i = 1; i <= digit; i++) rezult *= i; return rezult; // передаем значение факториала в главную функцию } Функция factorial принимает параметр – целое число, вычисляет его факториал и передает полученное значение в главную функцию. Результат работы программы аналогичен предыдущему примеру. Функции Обратите внимание. Теперь функция factorial() имеет возвращаемый тип данных int. Тип данных возвращаемого значения в строке int rezult = 1; должен совпадать с типом данных в строке int faktorial(int digit) Функции Обмен информацией между вызываемой и вызывающей функциями осуществляется с помощью механизма передачи параметров. Передача параметров выполняется следующим образом. Вычисляются выражения, стоящие на месте фактических параметров. Затем формальным параметрам присваиваются значения фактических. Передача параметров в функцию может осуществляться по значению, по указателю и по ссылке. Функции При передаче параметров по значению функция работает с копиями фактических параметров, и доступна к исходным значениям аргументов у нее нет. Эти копии создаются в оперативной памяти в момент вызова функции. По завершении работы вызываемой функции копии уничтожаются. За счет этого имена параметров в объявлении прототипа функции и ее описании могут отличаться от имен аргументов вызываемой функции. Функции В вызываемых функциях можно использовать точные имена аргументов вызывающей функции. Вызываемая функция в любом случае будет работать не напрямую с ними, а с их копиями. Функции При передаче параметров по указателю в функцию передается не переменная, а ее адрес. Для того,чтобы получить доступ к значению переменной, в теле функции нужно применить операцию разыменования (*). Следовательно, функция имеет доступ к ячейкам памяти, в которых хранятся значения аргументов. Для передачи фактического параметра используется операция взятия адреса (&). При передаче параметров по указателю никакой копии не создается, и функция работает непосредственно с фактическим параметром. Функции При передаче параметров по ссылке в функцию передается фактически разыменованный адрес переменной, являющейся аргументом. Таким образом, все изменения параметра, которые производит функция, выполняются непосредственно над переменной, ссылка на которую передана в функцию. Функции Таким образом, значение фактического параметра, переданного по значению, функция изменить не может, в отличие от значения аргумента, переданного по указателю или по ссылке. При передаче аргумента по указателю или по ссылке обычно предполагается, что этот аргумент будет изменен функцией. Однако указатели и ссылки могут использоваться и с целью оптимизации характеристик программы. Функции Как известно, если аргумент передается по значению, то в стеке создается копия этого значения. Например, при передаче аргумента, представляющего собой большую структуру, его размещение в стеке сопровождается неэкономным расходованием стекового пространства и ухудшением временных характеристик работы программы. В случае передачи аргумента по указателю или по ссылке в стек передается лишь адрес переменной, являющейся аргументом функции, что позволяет значительно улучшить временные характеристики работы программы. Функции Однако, при этом велика вероятность несанкционированного изменения аргумента в процессе работы функции. Во избежание подобных ситуаций используются указатели на константы, константные ссылки и константные указатели. Т.е. перед формальными параметрами, которые не должны изменяться при выполнении функции, требуется помещать модификатор const. Функции Общий вид заголовка функции: указатель на константу тип имя_функции (const тип_переменной *имя_переменной, …) константная ссылка тип имя_функции (const тип_переменной &имя_переменной, …) константный указатель тип имя_функции ( тип_переменной *const имя_переменной, …) Функции Пример программы, в которой параметры передаются в программу различными способами. Для наглядности опишем три функции. В первую функцию параметр передается по значению, во вторую – по указателю, в третью – по ссылке. В первом случае формальный параметр объявляется как переменная, во втором – как указатель, в третьем – как ссылка на переменную (оператор «&» указывает, что это ссылка). Функции При обращении к функциям фактическое значение аргумента а – переменная (в первую функцию передается копия а), аргумента b – адрес переменной b (во вторую функцию передается адрес переменной b), аргумента c – переменная (в третью функцию передается переменная с). В теле функций параметрам присваивается значение ноль. Для доступа к значению, хранящемуся по адресу, переданному в параметре b, используется операция разыменования (*). Функции … void function_1(int i); void function_2 (int *i); void function_3 (int &i); int main () { setlocale(LC_ALL,"Rus"); int a = 2, b = 3, c = 4; cout << "Исходные значения параметров:\n\n"; cout << "a = " << a << " b = " << b << " c = " << c << "\n\n"; cout << "Значения параметров в результате выполнения функций:\n\n"; Функции function_1(a); cout << "a = " << a; function_2(&b);//для передачи фактического параметра используется операция взятия адреса & cout << " b = " << b; function_3(c); cout << " c = " << c << "\n"; … } void function_1(int i) // параметр передается по значению { i = 0; } Функции void function_2 (int *i) // параметр передается по указателю { (*i) = 0; // при подстановке фактического параметра для получения его значения применяется операция разадресации * } void function_3 (int &i) // параметр передается по ссылке { i = 0; } Функции Результат работы программы: Функции В С++ существует возможность поместить описания функций в отдельный файл. В таком случае необходимо подключать файл с функциями, как в случае с подключением стандартных заголовочных файлов. Есть два способа описания функций в отдельном файле: создание файла типа *.cpp, в котором описываются функции; создание файлов типа *.cpp и *.h. К хорошему стилю программирования относится второй способ. Перегрузка функций Язык C++ позволяет связать с одним и тем же именем функции различные описания функций, то есть возможно существование нескольких функций с одинаковым именем. Эта возможность называется перегрузкой имени функции. Перегрузка функции – описание нескольких функций (двух или более) с одинаковым именем, но различными параметрами. Перегруженные функции создаются для того, чтобы избежать дублирования имен функций, выполняющих сходные действия, но с различной программной логикой. Перегрузка функций Возможность использования одинаковых идентификаторов для выполнения близких по смыслу, но, возможно, алгоритмически различных действий называется |