245.64K
Категория: ПрограммированиеПрограммирование

Функции и указатели

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));
}
English     Русский Правила