Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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




Передача имен функций в качестве параметров

Функцию можно вызвать через указатель на нее. Для этого объявляется указатель соответствующего типа и ему с помощью операции взятия адреса присваивается адрес функции:

void f(int a){ /*…*/ } // определение функции

void (*pf)(int); // указатель на функцию

pf=&f; //указателю присваивается адрес функции

//(можно написать pf=f;)

pf(10); //функция f вызывается через указатель pf

//(можно написать (*pf)(10))

Для того чтобы сделать программу легко читаемой, при описании указателей на функции используют переименование типов (typedef). Можно объявлять массивы указателей на функции (это может быть полезно, например, при реализации меню):

//Описание типа PF как указателя

//на функцию с одним параметром типа int:

typedef void (*pf)(int);

//Описание и инициализация массива указателей:

pf menu[]= {&new, &open, save};

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

menu[1](10);

Здесь new, open, и save - имена функций которые должны быть объявлены ранее. Указатели на функции передаются в программу таким же образом как и параметры других типов:

#include<iostream.h>

typedef void (*PF)(int);

void f1(PF pf)

{ //функция f1 получает в качестве параметра указатель типа pf

pf(5) //вызов функции, переданной через указатель

}

void f(int i) {cout <<i}

int main()

{

f1(f);

return 0;

}

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

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

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

Компилятор определяет, какую именно функцию требуется вызвать, по типу фактических параметров. Этот процесс называется разрешением перегрузки (перевод английского слова resolution в смысле «уточнение»). Тип возвращаемого функцией значения в разрешении не участвует. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать функцию с наиболее подходящими аргументами и выдать сообщение, если такой не найдется. Допустим, имеется четыре варианта функции, определяющей наибольшее значение:

 

// Возвращает наибольшее из двух целых:

int max(int, int);

// Возвращает подстроку наибольшей длины:

char* max(char*, char*);

// Возвращает наибольшее из первого параметра и длины второго:

int max (int, char*);

// Возвращает наибольшее из второго параметра и длины первого:

int max (char*, int);

void f(int a, int b, char* c, char* d)

{

cout << max (a,b) << max (c,d) << max (a,c) << max (c,b);

}

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

Если точного соответствия не найдено, выполняются продвижения порядковых типов в соответствии с общими правилами (см. [1] с. 38 и приложение 3), например, bool и char в int, float и double и т.п. Далее выполняются стандартные преобразования типов, например, int в double или указателей в void*. Следующим шагом является выполнение преобразований типа, заданных пользователем (об этих преобразованиях рассказывается во второй части [1], с. 195), а также поиск соответствий за счет переменного числа аргументов функций. Если соответствие на одном и том же этапе может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке.

Неоднозначность может появиться при:

· преобразовании типа;

· использовании параметров-ссылок;

· использовании аргументов по умолчанию.

Ниже приведены правила описания перегруженных функций.

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

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

· Функции не могут быть перегружены, если описание их параметров отличается только модификатором const или использованием ссылки (например, int и const int или int&).


Лабораторная работа № 11
Исследование способов работы с функциями

ЦЕЛЬ РАБОТЫ: совершенствование навыков в программировании с использованием указателей, исследование способов передачи параметров в функцию и порядка возвращения параметров из функции

Выполнение работы: освоить теоретический материал, выполнить общее для всех задание I и в соответствии с вариантом составить программу (задание II).

Задание I

Исследовать механизм перегрузки и способы передачи параметров при реализации пользовательских функций

1. Исследование способа передачи параметров в функцию по значению

· реализовать в среде программирования следующий листинг:

void Swap(int a, int b);

int main(int argc, char* argv[])

{

int x,y;

cout<<"\nEnter two numbers: ";

cin>>x>>y;

cout<<"\nx="<<x<<", y="<<y;

Swap(x,y);

cout<<"\nx="<<x<<", y="<<y;

cout<<endl;

return 0;

}

void Swap(int a, int b)

{

int c;

c=a;

a=b;

b=c;

return;

}

· с использованием режима отладки исследовать процесс исполнения программы в микропроцессоре. Обратить внимание на способ и место хранения значений локальных переменных a,b и c.

2. Исследование способа передачи параметров в функцию по адресу

· реализовать в среде программирования следующий листинг:

void Swap(int *a, int *b);

int main()

{

int x,y;

cout<<"\nEnter two numbers: ";

cin>>x>>y;

cout<<"\nx="<<x<<", y="<<y;

Swap(&x,&y);

cout<<"\nx="<<x<<", y="<<y;

cout<<endl;

return 0;

}

void Swap(int *a, int *b)

{

int c;

c=*a;

*a=*b;

*b=c;

return;

}

· с использованием режима отладки исследовать процесс исполнения программы в микропроцессоре. Обратить внимание на способ и место хранения значений локальных переменных a,b и c;

· реализовать в среде программирования следующий листинг:

void Swap(int &a, int &b);

int main()

{

int x,y;

cout<<"\nEnter two numbers: ";

cin>>x>>y;

cout<<"\nx="<<x<<", y="<<y;

Swap(x,y);

cout<<"\nx="<<x<<", y="<<y;

cout<<endl;

return 0;

}

void Swap(int &a, int &b)

{

int c;

c=a;

a=b;

b=c;

return;

}

· с использованием режима отладки исследовать процесс исполнения программы в микропроцессоре. Обратить внимание на способ и место хранения значений локальных переменных a,b и c;

· сделать выводы по рассмотренным методам.

3. Исследование порядка возвращения параметров из функции

· реализовать в среде программирования следующий листинг:

int* GetMem();

int main()

{

int *a;

a=GetMem();

cout<<"\n a is "<<a;

cout<<"\n*a is "<<*a;

cout<<endl;

return 0;

}

int* GetMem()

{

int *c=new int(5);

return c;

}

· с использованием режима отладки исследовать процесс исполнения программы в микропроцессоре;

· сделать выводы.

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

void PrintData(int *s, int N);

void PrintData(char *w);

void main()

{

int *a,n; char str[50];

cout<<”\nEnter the array size: “; cin>>n;

a=new int[n];

for (int i=0;i<n;i++) a[i]=rand()%101-50;

PrintData(a,n);

cout<<”\nEnter a string: “; cin>>str;

PrintData(str);

return;

}

void PrintData(int *s, int N)

{

cout<<endl;

for (int i=0;i<N;i++) cout<<s[i]<<” “;

return;

}

void PrintData(char *w)

{

cout<<endl<<w; return;

}

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

Задание II

В соответствии с вариантом составить и реализовать программы:

1. Даны 4 натуральных числа. Вычислить их наибольший общий делитель, используя подпрограмму для вычисления наибольшего общего делителя двух чисел.

2. Даны координаты вершин двух треугольников. Определить, какой из них имеет большую площадь.

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

4. Два натуральных числа называются "дружественными", если каждое из них равно сумме всех делителей другого, за исключением его самого (например, 284 и 220). Найти все пары "дружественных" чисел, не превосходящих заданного натурального числа.

5. Даны длины сторон треугольника. Вычислить длины медиан треугольника, сторонами которого являются медианы исходного треугольника.

6. Вычислить площадь произвольного выпуклого шестиугольника, заданного координатами вершин.

7. Даны длины сторон треугольника. Вычислить среднее арифметическое длин биссектрис этого треугольника.

8. Вычислить площадь полной поверхности правильной пятиугольной пирамиды, заданной длиной ребра.

9. Составить программу, которая будет вычислять сумму нужного числа n членов данной арифметической прогрессии по любым двум ее членам, номера которых известны. Примечание: , a 1 – первый член прогрессии; d – разность прогрессии; n – номер взятого члена, sn – сумма первых n членов арифметической прогрессии.

10. Составить программу, которая будет вычислять сумму нужного числа n членов данной арифметической прогрессии по любому члену прогрессии, номер которого известен, и разности прогрессии. См. примечание к задаче 9.

11. Три точки заданы своими координатами на плоскости. Найти площадь и длины диагоналей параллелограмма, вершинами которого являются эти точки.

12. Вычислить периметры трех треугольников и их среднее арифметическое. Если каждый из треугольников задается координатами своих вершин.

13. Найти площадь полной поверхности правильной n - угольной пирамиды по стороне основания при n = 4.

14. Сгенерировать члены ряда Фибоначчи, не превосходящие заранее заданного числа n. Проверить, что если число Фибоначчи f (k > 4) - простое, то и k - простое.

15. Вычислить площадь произвольного выпуклого пятиугольника, заданного координатами вершин.

16. Составить программу, которая будет вычислять сумму нужного числа n членов данной геометрической прогрессии по любому члену прогрессии, номер которого известен, и знаменателю прогрессии.

Примечание: , , b 1 – первый член прогрессии; q – знаменатель прогрессии; n – номер взятого члена, sn – сумма первых n членов геометрической прогрессии.

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

18. Вычислить члены ряда Фибоначчи, не превосходящие заранее заданного числа n. Проверить для нескольких четверок fi, fi + 1, fi + 2, fi + 3 последовательные члены ряда Фибоначчи справедливость соотношения .

19. Запрограммировать игру "Угадай число". Программа спомощью генератора случайных чисел выбирает целое число в диапазоне от 0 до 9. Угадать это число за три попытки. После каждой попытки сообщается больше или меньше названное число задуманного.

20. Найти все простые числа в промежутке между натуральными числами а и b (а > 2000, b - а ≥ 20)

21. Дано целое число а. Вычислить , где .

22. Сколькими способами можно отобрать команду в составе m человек из n кандидатов? Провести вычисления при m =5, n = 8; при m =6, n = 11.

23. n интервалов заданы координатами своих концов на координатной прямой и пронумерованы. Задана также точка х на этой прямой. Выяснить, скольким интервалам принадлежит точка х, указать их номера.

24. Даны три пары комплексных чисел, представленных в алгебраической форме. Организовать в виде подпрограммы выполнение четырех арифметических действий над парой комплексных чисел. Составить программу выполнения этих действий для каждой пары заданных чисел.

25. Даны координаты вершин треугольника и координаты двух точек на плоскости. Определить, лежат ли они внутри треугольника.

 





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


Дата добавления: 2014-11-16; Просмотров: 590; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.079 сек.