Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОАиП.docx
Скачиваний:
127
Добавлен:
09.03.2016
Размер:
139.71 Кб
Скачать

52.Использование указателей на функцию.

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

В некоторых типах программ пользователь может выбирать некоторый вариант из списка возможных действий. Например, в системе подсчета может быть меню более чем с 20 вариантами. Когда выбор сделан, программа выполняет соответствующую функцию. Это может быть сделано двумя способами. Как правило, с этой целью используется оператор switch. Тем не менее в приложениях, где требуется высокая производительность, лучше применять другой способ. Можно использовать массив указателей, содержащих адреса функций. Выбор, сделанный пользователем, декодируется и используется для индексации массива указателей, вызывая выполнение необходимой функции. Этот метод гораздо быстрее, чем метод использования switch.

Для того, чтобы понять, как можно использовать массив указателей на функции вышеприведенным способом, представим, что необходимо создать простейшую систему инвентаризации, позволяющую вводить, удалять и просматривать данные, а также выходить в операционную систему. Если функции, выполняющие эти действия, называются соответственно enter(), del(), review() и quit(), то следующий фрагмент кода корректно инициализирует массив указателей на функции: void enter(void), del(void), review(void), quit(void); int menu(void); void (*options[])(void) = { enter, del, review, quit }; Необходимо обратить особое внимание на способ объявления массива указателей на функции, а также на использование круглых и квадратных скобок.

53.Передача указателя на функцию.

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

#include <stdio.h> void AddFive(int Number) { Number = Number + 5; }

void main() { int nMyNumber = 18; printf("Оригинальное число равно %d\n", nMyNumber); AddFive(nMyNumber); printf("Оригинальное число равно %d\n", nMyNumber);}

Тем не менее, проблема заключается в том, что Number , к которому ссылаются в AddFive является копией переменной nMyNumber , переданной в функцию, а не самой переменной. Тем самым строка Number = Number + 5 добавляет пять к копии этой переменной, при этом оригинальная переменная в main() не будет изменена. Попробуйте запустить программу и убедитесь в этом сами. Чтобы обойти данную проблему, мы можем передать в функцию указатель того места, где данное число содержится, тем самым она будет ожидать указатель на число, а не число. Для этого мы изменим void AddFive(int Number) на void AddFive(int* Number), добавляя звездочку. Вот данная программа с внесенными изменениями. Заметьте, что мы должны убедиться, что передаем адрес nMyNumber вместо самого числа. Это выполняется посредством добавления символа & , который (как вы уже знаете) читается как "по адресу".

#include <stdio.h> void AddFive(int* Number) { *Number = *Number + 5;}

void main(){ int nMyNumber = 18; printf("Оригинальное число равно %d\n", nMyNumber); AddFive(&nMyNumber); printf("Оригинальное число равно %d\n", nMyNumber);}

Попробуйте придумать свой пример использования передачи указателей в функцию. Заметьте важность использования символа * до Number в функции AddFive. Это необходимо для указания компилятору, что мы хотим добавить пять к числу, на которое указывает переменная Number, а не добавлять пять к самому указателю. Наконец, последнее, что стоит упомянуть о функциях, так это то, что вы можете возвращать указатели из них примерно так:

int * MyFunction();

 В данном примере MyFunction возвращает указатель на integer.