Студенту >> Язык программирования Си


Указатели и функции

Функции, как и другие объекты программы, располагаются в памяти ЭВМ. Любая область памяти имеет адрес, в том числе и та, в которой находятся функция. Имя функции без круглых скобок за ним представляет собой константный адрес этой области памяти. Таким образом, имея функции со следующими прототипами:

double sin(double x);
double cos(double x);
double tan(double x);

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

Можно описать и указатель на функцию. Например, для функции с аргументом типа double, возвращающей значение типа double, описание такого указателя будет выглядеть следующим образом:

double (*fn)(double x);

Здесь, как и в случае указателя на массив, круглые скобки увеличивают приоритет операции *. Если бы они отсутствовали, то была бы описан не указатель на функцию, а функция, возвращающая значение указателя на double.

После того, как описан указатель на функцию, становятся возможными следующие операции:

fn = sin; /* Настройка указателя на функцию sin */
a = fn(x); /* Вызов функции sin через указатель */
fn = cos; /* Настройка указателя на функцию cos */
b = fn(x); /* Вызов функции cos через указатель */ 

Можно описать массив указателей на функцию и проинициализировать его:

double (*fnArray[3])(double x) = { sin, cos, tan }; 

Теперь становится возможным следующий цикл:

for(i=0; i<3; i++)
printf( "F(x) = %lf\n", fnArray[i](x) ); 

Можно описать функцию возвращающую значение указателя на функцию:

double (*fnFunc(int i)) (double x)
{
   switch(i)
   {
       case 0 : return sin;
       case 1 : return cos;
       case 2 : return tan;
   }
} 

Описанная функция имеет параметр типа int и возвращает значение указателя на функцию с аргументом типа double, возвращающую значение типа double.

После описания функции fnFunc становится возможным следующий цикл:

for(i=0; i<3; i++)
printf( "F(x) = %lf\n", fnFunc(i)(x) );  
НАВЕРХ