Функции могут возвращать указатели также как и любые другие типы. Важно помнить, что указатели – это не беззнаковые целые. Это адрес памяти некоторого типа данных, у них другая арифметика.
Пример – функция, возвращающая указатель на символ в месте, где найдено первое вхождение символа в строке:
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.
Рекурсия
В С функции могут вызывать сами себя. Простой пример.
int factr(int n)
{ int answer;
if(n == 1) return 1;
answer = factr(n-1)*n;
return (answer);
}
Задача о ханойских башнях.
#include <stdio.h>
void solveTowers(int count, char sourse,
char destination, char spare)
{
if (count == 1)
{
printf("Move top ring from %c to %c\n", sourse, destination);
}
else
{
solveTowers(count-1, sourse, spare,
destination);
solveTowers(1, sourse, destination, spare);
solveTowers(count-1, spare, destination,
sourse);
}
}
int main()
{
solveTowers(4,'A','B','C');
getchar();
return 0;
}
1.Указатели на функции
2.Структуры
3.Доступ к членам структуры
4.Присваивание структур
5.Массивы структур
Хотя функция – это не переменная, она имеет физическое положение в памяти, которое может быть присвоено указателю. Адрес, присвоенный указателю, является входной точкой в функцию. Указатель может использоваться вместо имени функции. Он также позволяет передавать функции как обычные аргументы в другие функции.
Адрес функции получается при использовании имени функции без скобок и аргументов. Пример:
#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.
Бывают моменты, когда выгодно передавать функции в процедуры или хранить массивы функций. Пример: