Урок 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. Определения таких функций непосредственно подставляются в точку вызова, что, с одной стороны, увеличивает объём исполняемого кода, но, с другой стороны, позволяет экономить время его выполнения, поскольку не используется дорогая по времени операция вызова функции.

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов