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

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

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

char *match(char c, char *s)

{ register int count;

count = 0;

while(c!=s[count] && s[count]) count++;

if(s[count]) return (&s[count]);

else return NULL;

}

Функция match() пытается вернуть указатель на позицию в строке, где первый раз найден символ. Если не найдено соответствие, возвращается указатель, содержащий NULL.

  1. Рекурсия

В С функции могут вызывать сами себя. Простой пример.

int factr(int n)

{ int answer;

if(n == 1) return 1;

answer = factr(n-1)*n;

return (answer);

}

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

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

Адрес функции получается при использовании имени функции без скобок и аргументов. Пример:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <math.h>

#define PI 3.1415

double del2(double a, double b, double eps, double (*f)(double));

int main(void)

{

double (*p)(double);

p = sin;

double a = -PI/2, b = PI/2, eps = 0.0001;

printf("Root = %lf\n", del2(a,b,eps,p));

printf("Root = %lf\n", del2(a,b,eps,sin));

return 0;

}

double del2(double a, double b, double eps, double (*f)(double))

{

if(b<a) {

puts("Left bigger than right");

exit(0);

}

if(eps <= 0) {

puts("Eps <= 0");

exit(0);

}

if(f(a) == 0) return a;

if(f(b) == 0) return b;

while(b-a >= eps) {

double x=(a+b)/2;

if(f(a)*f(x) < 0.) a=x;

else if(f(x) == 0.) return x;

else b=x;

}

return (a+b)/2;

}

Когда вызывается del2(), ей передаются числа с плавающей точкой двойной точности и один указатель на функцию. Скобки вокруг *f необходимы для правильной интерпретации компилятором данного выражения.

При объявлении указателя на функцию можно использовать прототип, оставив имена параметров пустыми.

Рассмотрим работу функции sin() в функции del2(). Оператор

if(f(a) == 0) return a;

осуществляет вызов функции, в данном случае sin(), с помощью f, который указывает на данную функцию. Вызов происходит с аргументом a.

Бывают моменты, когда выгодно передавать функции в процедуры или хранить массивы функций. Пример:

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <string.h>

void enter(void), del(void); void review(void), quit(void);

int menu(void);

void (*options[])(void) = {

enter,

del,

review,

quit

};

int main(void)

{

int i;

i = menu();

(*options[i])();

getchar();

return 0;

}

int menu(void)

{

char ch;

do {

printf("1. Enter\n");

printf("2. Delete\n");

printf("3. Review\n");

printf("4. Quit\n");

printf("Select a number:");

ch = getche();

printf("\n");

}while(!strchr("1234", ch));

return ch-49;

}

void enter(void)

{ printf("In enter.");}

void del(void)

{ printf("In del.");}

void review(void)

{ printf("In review.");}

void quit(void)

{ printf("In quit.");

exit(0);

}