Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
61.doc
Скачиваний:
131
Добавлен:
11.05.2015
Размер:
451.58 Кб
Скачать

44. Указатели на функции. Массивы указателей на функции. Указатель на функцию в качестве аргумента другой функции.

Указатели на функции – очень мощное средство языка С. Функция располагается в памяти по определенному адресу, который можно присвоить указателю в качестве его значения. Адресом функции является ее точка входа. Именно этот адрес используется при вызове функции. Так как указатель хранит адрес функции, то она может быть вызвана с помощью этого указателя. Он позволяет также передавать ее другим функция в качестве аргумента.

В программе на С адресом функции служит ее имя без скобок и аргументов.

Как и объекты любых других типов, указатели могут быть собраны в массив. В следующем операторе объявлен массив из 10 указателей на объекты типа int:

int*x[10];

Для присвоения, например адреса переменной var третьему элементу массива указателей, необходимо написать:

x[2]=&var;

В результате этой операции, следующее выражение принимает то же значение, что и var:

*x[2]

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

void display_array(int *q[])

{

int t;

for(t=0; t<10; t++)

printf("%d ", *q[t]);

}

Необходимо помнить, что q – это не указатель на целые, а указатель на массив указателей на целые. Поэтому параметр q нужно объявить как массив указателей на целые.

В языке С нельзя передать весь массив как аргумент функции. Однако можно передать указатель на массив, т.е. имя массива без индекса. Например, в представленной программе в func1() передается указатель на массив i:

int main(void)

{

int i[10];

func1(i);

/*…*/

}

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

voidfunc1(int*x) //указатель

{

……..

}

Или как

voidfunc1(intx[10]) //массив определенного размера

{

}

и наконец как

voidfunc1(intx[]) // массив без определенного размера

{

}

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

voidfunc1(intx[32])

{

……

}

И при этом программа будет выполнена правильно, потому что компилятор не создает массив из 32 элементов, а только подготавливает функцию к приему указателя.

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

Функция, которая получает 2 целых числа и возвращает сумму, произведение, разность и деление данных чисел.

#include <stdio.h>

void fff(int, int, int*, int*,int*, double*);

void main()

{

int x, y, sum, pr, raz;

double del;

printf(“Vvedite dva chelich chisla:”);

scanf(“%d%d”, &x,&y);

fff(x,y, &sum, &pr, &raz, &del);

printf(“%d+%d=%d\n”, x,y,sum);

printf(“%d-%d=%d\n”, x,y,raz);

printf(“%d*%d=%d\n”, x,y,pr);

printf(“%d/%d=%.2lf\n”, x,y,del);

}

void fff(int a, int b, int*p1, int*p2, int*p3, double *p4)

{

*p1=a+b;

*p2=a*b;

*p3=a-b;

*p4=(double)a/b;

}