Similar presentations:
Функции и указатели
1.
ФУНКЦИИ И УКАЗАТЕЛИ2.
Рекурсия2
Функция может вызывать саму себя. Это
называется рекурсией, которая может быть прямой
и косвенной. Если функция вызывает саму себя –
это прямая рекурсия, если же она вызывает другую
функцию, которая в свою очередь вызывает первую,
то это косвенная рекурсия
Важно рекурсию когда-нибудь прекратить (задать
некоторое условие), иначе рекурсивная функция
будет вызывать себя бесконечное число раз.
3.
Рекурсия3
Пример использования рекурсии рассмотрим на
программе нахождения определённого члена ряда
Фибоначчи:
1,1,2,3,5,8,13,21,34…
Каждое число ряда представляет собой сумму двух
предыдущих чисел. В общем случае n-e число равно
сумме (n-2)-го и (n-1)-го чисел.
Для рекурсивных функций необходимо условие
прекращения рекурсии, в ряду Фибоначчи
условием прекращения будет n<3.
4.
Рекурсияint fib(int n)
{
if (n<3)
return 1;
else
return (fib(n-2)+fib(n-1));
}
4
5.
УХОД В РЕКУРСИЮ5
6.
ВОЗВРАЩЕНИЕ ИЗ РЕКУРСИИ6
7.
ФУНКЦИИ С ПЕРЕМЕННЫМЧИСЛОМ ПАРАМЕТРОВ
7
Можно передавать данные, не описывая их в прототипе
или заголовке функции. Описание таких данных
заменяется … (тремя точками).
int f(…)
При определении функции компилятору неизвестны ни
количество параметров, ни их типы. Количество
параметров и их типы становятся известными только при
вызове функции.
8.
ФУНКЦИИ С ПЕРЕМЕННЫМ ЧИСЛОМПАРАМЕТРОВ
8
Список параметров совсем пустой быть не может, должен
быть прописан хотя бы один явный параметр, адрес
которого мы можем получить при выполнении программы.
Аргументы передаются через стек. Целочисленные данные
преобразуются к типу int, с плавающей точкой – к типу
double.
9.
ФУНКЦИИ С ПЕРЕМЕННЫМ ЧИСЛОМПАРАМЕТРОВ
9
int sum(int k, ...)
{
int sum = 0;
int *p = &k;
while(k--)
{
p++;
sum += *p;
}
return sum;
}
////////////
printf("5 plus 6 is %d\n", sum(2, 5,6));
printf("Sum of 1, 2, 3 is %d\n", sum(3, 1 ,2 ,3));
10.
Указатель на функцию10
Указатель на функцию – тип переменной, которой
можно присваивать адрес точки входа в функцию
(адрес первой исполняемой команды).
Тип_результата(*имя_указателя)(типы пар.);
int (*fun)(int, char*);
11.
Указатель на функциюint fact(int n);
int sqrt_int(int n);
int (*currentFun)(int);
int fact(int n)
{
if(n == 1 || !n) return 1;
return fact(n-1)*n;
}
int sqrt_int(int n)
{
return (int)sqrt((float)n);
}
11
12.
Указатель на функцию12
switch (choice)
{
case '1': currentFun = sqrt_int; break;
case '2': currentFun = fact; break;
}
printf("The result is %d", currentFun(n));
13.
ПЕРЕДАЧА ЧЕРЕЗ УКАЗАТЕЛЬ13
void fun(int a1)
{
a1++;
}
void main(void)
{
int a=5;
printf("a = %d \n", a);
fun(a);
printf(“a = %d\n", a);
}
14.
ПЕРЕДАЧА ЧЕРЕЗ УКАЗАТЕЛЬ14
void fun(int *a1)
{
(*a1)++;
}
void main(void)
{
int a=5;
printf("a = %d \n", a);
fun(&a);
printf(“a = %d\n", a);
}
15.
Передача массива в функцию15
С указанием статического размера
int sum(int x[5])
{
int res=0;
for(int i=0; i<5; i++)
res+=x[i];
return res;
}
16.
Передача массива в функцию16
Без указания размера
int sum(int x[], int n)
{ int res=0;
for(int i=0; i<n; i++)
res+=x[i];
return res;
}
17.
Передача массива в функцию17
Через указатель
int sum(int *x, int n)
{
int res=0;
for(int i=0; i<n; i++)
res+=*(x+i);
return res;
}
// В массиве изменений НЕТ!
18.
Выделение места под массив вфункции
18
int mem_init(int n)
{
return (int*)calloc(n,sizeof(int));
}
void mem_init1(int n, int **m)
{
*m= (int*)calloc(n,izeof(int));
}