Урок 9.3. Вызов функции
Использование функций происходит посредством вызова функций.
Вызов функции – это выражение, значением которого является значение, возвращаемое функцией. |
В Си функция не может быть значением переменной, но можно определить ссылку (указатель) на функцию. С этой ссылкой можно уже манипулировать как с переменной: передавать ее функциям, помещать в массивы и т.п. Существует два способа вызова функции:
первый – <имя функции>(<аргументы>)
второй – (*<указатель на функцию>)(<аргументы>) или так:
второй – <указатель на функцию>(<аргументы>)
где <указатель на функцию> – это переменная, содержащая адрес функции. Адрес функции может быть присвоен указателю оператором
<указатель на функцию> = <имя функции>
Первый способ вызова функции является общепринятым для всех языков программирования. В качестве примера можно рассмотреть функцию нахождения максимального из двух целых чисел. Пусть она определяется следующим образом:
int max2(int x,int y) { return(x>y?x:y); // возвращает наибольшее из двух значений } //Тогда в некоторой функции может встретиться такой фрагмент: int x,y,z; printf ("Введите 2 целых числа: "); scanf("%d %d",&x,&y); z = max2(x,y); printf(" Наибольшее из двух =%d",z); |
При его исполнении запрашивается ввод двух целых десятичных чисел, с помощью функции max2 из них выбирается наибольшее, которое присваивается переменной z и затем выводится сообщение " Наибольшее из двух = ", вслед за которым выдается значение z.
Второй способ вызова функции через указатель является специфичным для языка Си. Вызовем функцию max2 из предыдущего примера при помощи указателя на функцию:
int (*pf)(int, int); //объявлен pf - указатель на функцию с двумя целыми //параметрами и возвращающей целое число int x,y,z; printf ("Введите 2 целых числа: "); scanf("%d %d",&x,&y); pf = &max2; // pf получает адрес функции max2 //или можно и так: pf = max2; z = pf(x,y); //вызов функции max2 printf(" Наибольшее из двух =%d",z); |
Приведем еще один пример программы иллюстрирующий вызовы функций, в том числе встроенных, через указатели. Вызов пользовательской функции fn(), встроенных функций sin(), cos(), pow() – возведение в степень.
#include <math.h> #include <conio.h> #include <stdio.h> //ptofn - новое имя для типа указатель //на функцию с одним параметром типа double //и возвращающую значение типа double typedef double(* ptofn)(double); //ptofn_void - новое имя для типа указатель //на функцию без параметров и ничего не возвращающую typedef void(* ptofn_void)(); //pf - указатель на функцию с одним параметром //типа double и возвращающую значение типа double double (* pf)(double); void fn() { printf("Function fn()\n"); } void main() { ptofn_void p; p = fn; //одинаковые вызовы одной и той же функции fn() (*p)(); p(); //вызов функции sin посредством указателя на функцию ptofn q; q=sin; printf("sin(30gr)=%f\n", (*q)(3.14/6.)); //вызов функции cos посредством указателя на функцию pf=&cos; printf("cos(30gr)=%f\n", pf(3.14/6.)); //попытка вызов функции pow посредством указателя //на функцию с несоответствующим списком параметров, //у функции pow их два //q=&pow; //Ошибка //исправление ошибки, объявление правильного указателя - g double (*g)(double, double); g=&pow; printf("sqrt(2.0)=%f\n", (*g)(2.,0.5)); _getch(); } |
Еще один пример вызова функций через указатель. Функции fn0(),fn1(),fn2() вызываются посредством другой функции – fn(), которой передается целое число, использующееся как индекс в массиве адресов функций.
#include <conio.h> #include <iostream> using namespace std; void f0() { cout << "Function fn0()" << endl; } void f1() { cout << "Function fn1()" << endl; } void f2() { cout << "Function fn2()" << endl; } //fn - функция с одним параметром целого типа, //возвращающая указатель на функцию типа void void (*fn(int n))() { //a - массив указателей на функции //без параметров с возвращаемым значением типа void void (*a[3])() = {f0, f1, f2}; return a[n]; } void main() { void (*p)();//указатель на функцию //вызов функции, которая вызовет функцию, //по номеру функции в массиве p = fn(0); (*p)(); //или p(); p = fn(1); (*p)(); p = fn(2); (*p)(); _getch(); } |
Вызов функций С в С++. С++ преобразует имена функций во внутреннее представление. Для того, чтобы не производить преобразование имен функций С при их вызове в С++ надо в начале их объявления указывать
extern ”C”.
Например,
extern ”C” void strcpy(char *, const char *);
Несколько функций можно объявить так:
extern ”C”
{ void strcpy(char *, const char *);
int strcmp(const char *, const char *);
}
Такие объявления размещаются только на глобальном уровне.
Inline функции. Если функция относительно маленькая, то вместо вызова такой функции в программу можно вставить код функции Такие функции называются inline (встраиваемые или подставляемые функции) и представляют особый класс функций— функции, объявленные с указанием ключевого слова inline. Определения таких функций непосредственно подставляются в точку вызова, что, с одной стороны, увеличивает объём исполняемого кода, но, с другой стороны, позволяет экономить время его выполнения, поскольку не используется дорогая по времени операция вызова функции.
Оставить комментарий