Массивы указателей на функции

Такие массивы по смыс­лу ничем не отличаются от массивов других объектов, однако форма их определения несколько необычна:

тип (*имя массива [размер]) (спецификация_параметров);

где тип определяет тип возвращаемых функциями значений;

имя_массива - произвольный идентификатор;

размер - количество элементов в* массиве;

спецификация_параметров - определяет состав и типы параметров функций. Пример:

int (*parray [4]) (char);

где parray - массив указателей на функции, каждому из которых можно присвоить адрес определенной выше функции int fic (char) и адрес любой функции с прототипом вида:

int имя_функции (char);

Массив в соответствии с синтаксисом языка является произ­водным типом наряду с указателями и функциями. Массив функций создать нельзя, однако, как мы показали, можно опре­делить массив указателей на функции. Тем самым появляется возможность создавать "таблицы переходов" (jump tables), или "таблицы передачи управления". С помощью таблицы перехо­дов удобно организовывать ветвления с возвратом по результатам анализа некоторых условий. Для этого все ветви обработки (например, N+1 штук) оформляются в виде однотипных функ­ций (с одинаковым типом возвращаемого значения и одинако­вой спецификацией параметров). Определяется массив указа­телей из N+1 элементов, каждому элементу которого присва­ивается адрес конкретной функции обработки. Затем формиру­ются условия, на основе которых должна выбираться та или иная функция (ветвь) обработки. Вводится индекс, значение ко­торого должно находиться в пределах от 0 до N включительно, где (N+1) - количество ветвей обработки. Каждому условию ставится в соответствие конкретное значение индекса. По кон­кретному значению индекса выполняются обращение к элемен­ту массива указателей на функции и вызов соответствующей функции обработки:

имя массива [индекс] (список_фактических_параметров);

(*имя массива [индекс]) (список_фактических_параметров);

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

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "locale.h"

#include "stdlib.h"

#define N 2

void act0(char * name)

{

printf("%s: Работа завершена!\n",name);

_getch();

exit(0);

}

void act1(char * name)

{

printf("%s: работа l\n",name);

}

void act2(char * name)

{

printf("%s: работа 2\n",name);

}

int _tmain(int argc, _TCHAR* argv[])

{

/* Массив указателей на функции: */

setlocale(LC_ALL,"Russian");

void (*pact[])(char *)={act0,act1,act2};

char string[12];

int number;

printf("\n\nВводите имя: ");

scanf("%s",string);

printf("Вводите номера работ от 0 до %d:\n",N);

while (1)

{

scanf("%d",&number);

/* Ветвление по условию */

pact[number](string);

}

_getch();

return 0;

}

Пример выполнения программы:

Вводите имя: Peter

Вводите номера работы от 0 до 2:

Peter: работа 1

Peter: работа 1

Peter: работа 2

Peter: Работа Завершена!

В программе для упрощения нет защиты от неверно введен­ных данных, т.е. возможен выход индекса за пределы, опреде­ленные для массива pact[ ] указателей на функции. При такой ситуации результат непредсказуем.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: