- •1. Краткие теоретические сведения
- •1.1. Знакомство с функциями
- •1.2. Описание функции
- •1.3.1. Тело функции
- •1.3.2. Формальные параметры функции
- •1.3.3. Обращение к функции
- •1.3.4. Фактические параметры.
- •1.4. Формальные и фактические параметры функции
- •1.5. Описание и объявление функции. Прототип функции
- •1 Способ - Перед main().
- •2 Способ - После main ().
- •1.6. Передача параметров в функцию. Изменяемые значения параметров
- •1.6.1. Передача параметров
- •1.6.2. Передача параметров по значению
- •1.6.3. Передача параметров по ссылке
- •1.6.4. Передача параметров по указателю
- •1.7. Механизм обращения к функции и передача данных
- •1.8. Локальные и глобальные переменные. Время жизни и область действия (видимости) переменных
- •1.8.1. Представление об области видимости переменных
- •1.8.2. Объявление локальных переменных
- •1.8.3. О конфликте имен
- •1.8.4. Глобальные переменные
- •1.8.5. Если имена глобальных и локальных переменных конфликтуют
- •1.9. Принцип сокрытия данных внутри функции. Принцип локализации имен
- •1.10. Передача одномерных массивов как параметров функции
- •1.11. Передача многомерных массивов в функцию
- •1.12. Рекурсивные функции
- •1.13. Аргументы по умолчанию
- •1.14. Встраиваемые функции (inline)
- •1.15. Перегрузка функций
- •1.16. Указатель на функцию
- •1.17. Шаблоны функций
- •1.18. Использования библиотеки этапа выполнения
- •1.18.1. Использование функций библиотеки этапа выполнения
- •1.18.2. Изучение функций библиотеки этапа выполнения
- •1.18.3. Использование функций api
- •1.19. Изменение значений параметров функции
- •1.19.1. Почему функции обычно не могут изменить значения параметров
- •1.19.2. Изменение значения параметра
- •1.19.3. Использование ассемблерных листингов для лучшего понимания работы компилятора
- •1.20. Примеры решения задач с использованием механизма функций
- •2. Задание
- •2.4. Задания для выполнения на занятиях
- •2.4.1. Задание 1. Функции пользователя-использование формул
- •2.4.1.1. Условие задания
- •2.4.1.2. Пример для варианта 30
- •2.4.1.3. Программа
- •2.4.1.4. Тестирование
- •2.4.2. Задание 2. Функции пользователя при работе с массивами
- •2.4.2.1. Условие задания
- •2.4.2.2. Пример для варианта 30
- •2.4.2.3. Программа
- •2.4.2.4. Тестирование
- •2.4.3. Задание 3. Функции пользователя при работе с массивами
- •2.4.3.1. Условие задания
- •2.4.3.2. Пример для варианта 30
- •2.4.3.3. Программа
- •2.4.3.4. Тестирование
- •2.4.4. Задание 4. Вычисление выражений с использованием функций
- •2.4.4.1. Условие задания
- •2.4.4.2. Пример для варианта 30
- •2.4.4.3. Программа
- •2.4.4.4. Тестирование
- •2.4.5. Задание 5. Вычисление интеграла методом трапеций
- •2.4.5.1. Условие задания
- •2.4.5.2. Пример для варианта 30
- •2.4.5.3. Программа
- •2.4.5.4. Тестирование
- •2.4.5.5. Типичные ошибки при выполнении работы
- •Вопросы для самоконтроля
- •Литература
- •1. Краткие теоретические сведения 2
- •1.1. Знакомство с функциями 2
1 Способ - Перед main().
Если функции объявлять перед главной функцией, то прототипы для этих функций не нужны.
Описание функции фактически расположено перед текстом вызывающей программы. В этом случае описание функции есть одновременно и ее объявление.
Пример 13.9
// две вызываемые функции без параметров. Описание опережает обращение
void f1 (void) // описание функции f1
{
printf ("Функция 1\n");
}
void f2 (void) // описание функции f2
{
printf ("Функция 2\n");
}
void main (void) // функции известны до момента обращения
{
printf ("\nГлавная функция main\n");
f1 (); // обращение к функции f1
f2 (); // обращение к функции f2
}
В этом случае описание функций играет роль их объявления.
2 Способ - После main ().
Область объявления функций переместилась в самый конец программы, после main(). Что касается самого способа объявления функций, то он не поменялся. Но так как функции объявлены после main(), использовать их не получится, ведь порядок объявлений изменился и функция main() просто не будет видеть функции объявленные после. Так вот для того, чтобы эти функции можно было увидеть в main() существует понятие прототипа. Прототип функции - это заголовок функции, который объявляется перед функцией main(). И если объявить прототип функции, тогда функцию можно будет увидеть в main().
Хорошему стилю программирования соответствует способ объявления функций после main()!!!
Описание функции фактически расположено после текста вызывающей программы. Значит, обращение к функции появляется перед ее описанием. Чтобы функция стала известной вызывающей программе, кроме описания нужно еще и объявление функции. Объявление функции (в C это еще называется прототип) — это ее заголовок, за которым стоит знак завершения оператора «;».
Как правило, помимо описания функции в программу вставляется прототип функции (ее предварительное объявление). Прототип аналогичен заголовку функции, только на конце его ставится точка с запятой, а имена формальных параметров не указываются (остаются только типы):
Прототип может быть записан в начале программы, если функция глобальна, или в теле main, если функция локализована в main, или в теле любой функции, где функция известна локально. Прототип функции — это аналог описания переменных.
int Sum (int, double, char);
Пример 13.10
// те же самые функции без параметров. Прототип объявляет функцию
void f1 (void); // прототип функции f1
void f2 (void); // прототип функции f2
// обращение опережает описание
void main (void)
{
printf ("\nГлавная функция main\n");
f1 (); // обращение к функции f1
f2 (); // обращение к функции f2
}
// описание функций после вызывающей программы
void f1 (void) // описание функции f1
{
printf ("Функция 1\n");
}
void f2 (void) // описание функции f2
{
printf ("Функция 2\n");
}
Описание функции вынесено в отдельный файл. Такие файлы должны обладать возможностью быть легко подключаемыми к любой программе, использующей эти функции.
Прототип описывает компилятору интерфейс функции. Он сообщает компилятору тип возвращаемого значения функции, если таковое имеется, а также количество и типы аргументов. Компилятор получает возможность:
– правильно обрабатывать возвращаемое значение функции;
– следить за числом аргументов функции;
– контролировать применение корректных типов данных для аргументов функции.
Прототип функции является оператором, поэтому он должен завершаться точкой с запятой.
Простейший способ создания прототипа – скопировать из определения функции её заголовок и добавить точку с запятой.
Примеры операторов прототипа:
int sum(int a,int b);
void swap(int &a, int &b);
void sp(int a,int b,int &s, int &p);
В прототипе можно опускать имена переменных, вполне достаточно списка типов:
int sum(int , int );
void swap(int &, int &);
void sp(int ,int ,int &, int &);
В языке С++ прототипы и определения функций хранятся раздельно. Библиотечные файлы содержат скомпилированные коды функций, тогда как заголовочные файлы содержат прототипы функций.
Прототип функции должен находиться в программе до того места, где функция выполняется впервые. Обычно прототипы функций помещаются непосредственно перед определением функции main().
Обработка прототипов осуществляется во время компиляции и относится к категории статического контроля типов. Статический контроль типов позволяет обнаружить многие ошибки из числа тех, которые намного труднее выявить во время выполнения программы.
Пример 13.11
Описать функцию, которая осуществляет преобразование метров в футы (один метр равен 3.281 фута).
#include <iostream>
using namespace std;
double feet(double metres);//оператор прототипа
int main()
{
double metres;
cout<<”enter the weigth in metres: ”;
cin>>metres;
double feets=feet(metres);
cout<<metres<<” metres are ” ;
cout<<feets<<” feets\n”;
return 0;
}
double feet(double metres)//описание функции
{ return 3.281*metres; }
В результате выполнения программы получим следующие результаты:
enter the weigth in metres: 14
14 metres are 45.534 feets
Пример 13.12
Выполнить вычисление по формуле, используя функцию:
Вариант 1 |
Вариант 2 |
# include<stdio.h> # include<math.h>
double fn(double x,double y) {return fabs(x*x+y*y);}
void main() {double x,y,z; printf("Введите х и y"); scanf("%lf%lf",&x,&y); z=fn(x,y); printf("z равно %lf",z); } |
# include<stdio.h> # include<math.h>
double fn(double x,double y);
void main() {double x,y,z; printf("Введите х и y"); scanf("%lf%lf",&x,&y); z=fn(x,y); printf("z равно %lf",z); }
double fn(double x,double y) {return fabs(x*x+y*y);} |
|
|
Как видно из примера 13.12, описание функции может быть произведено до и после функции main, а объявление функции, т.е. задание ее прототипа необходимо производить до функции main. В примере 13.12 прототипом функции является строка double fn(double x,double y).
В качестве аргумента (передаваемого значения) функции можно использовать массив. Одним из способов объявления такой функции является строка:
тип <имя функции>(<тип элементов массива> *<имя массива>);
Пример 13.13
Объявить функцию, в качестве аргумента которой используется массив с именем ar, состоящий из 10 элементов типа int.
1 способ: void sort(int *ar);
2 способ: void sort(int ar[]);
3 способ: void sort(int ar[10]);
Внимание: 3 и 4 способы объявления функций в данной работе не рассматриваются.