Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Язык программирования Си++. Лекции.DOC
Скачиваний:
147
Добавлен:
02.05.2014
Размер:
775.17 Кб
Скачать
    1. Указатели и функции

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

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) );

    1. Оператор typedef

Описания, подобные описаниям предыдущего раздела, достаточно сложны для понимания. Для упрощения описаний сложных типов в языке Си предусмотрен оператор typedef. Его использование иллюстрируется следующим синтаксисом:

БНФ:

typedef описание_одного_имени

Под описанием_одного_имени подразумевается любое, сколь угодно сложное описание данного. Но в этом случае имя будет обозначать не имя данного, а имя нового типа, который соответствует типу данного и может быть использован в качестве имени типа в любых других определениях данных. Рассмотрим пример:

typedef double DArray[100];

...

DArray A, B, C;

Если бы в первом описании отсутствовало бы ключевое слово typedef, то имяDArrayпредставляло бы имя массива из 100 элементов типаdouble, для которого бы выделялся соответствующий объем памяти. При наличииtypedef компилятор будет воспринимать имяDArrayкак имя нового типа данных, а именно, типа массива из 100 элементов типаdouble. Очевидно, никакой памяти при этом не выделяется.

Во втором описании используется имя нового типа DArray. Каждое из определяемых имен A, B и C будет считаться массивом из ста элементов типаdouble, и для каждого из них будет выделен соответствующий объем памяти.

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

typedef double (*Fun)(double x); /*Тип указателя*/

Fun fnArray[3] = { sin, cos, tan }; /*Массив функций*/

Fun fnFunc(int i) /* Функция, возвращающая функцию */

{

switch(i)

{

case 0 : return sin;

case 1 : return cos;

case 2 : return tan;

}

}

Совершенно очевидно, что последние описания значительно понятнее.

Соседние файлы в папке C++