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

1.7 Рекурсивные и подставляемые функции

Рекурсивная функция – эта такая функция, которая содержит в себе вызов этой же функции, т.е. самовызывающая функция.

Рекурсивные функции желательно не использовать, если есть очевидное итерационное решение.

Пример. Вычисление факториала неотрицательного целого числа

long fact(int k) // Определение функции

{if(k<0) return 0;

if (k==0} return 1;

return k* fact(k-1);}

Void main()

{int n=5; long F_n=fact(n);

printf (“%d!=%ld”,n,F_n);}

На экран выведется: 5!=120

Функция прерывается при k==0, последнее выражение (1*fact(1-1)) , вычисляет k*(k-1)*(k-2)*(k-3)*(k-4)*1.

Подставляемая функция (inline-функция) – это функция, тело которой подставляется при каждом ее вызове. Такая функция определяется с помощью слова inline.

Inline-функция обрабатывается компилятором как встраивае­мая, т.е. вместо каждого вызова этой функции компилятор попытается подставить тело функции. При многократных вызовах код программы может значительно увеличиться, но скорость работы программы повысится за счет отсутствия вызовов этой функции.

Пример.

inline float mod(float x,float y)// Определение функции

{return sgrt(x*x+y*y);}

Void main()

{float f1=4.5, f2=-2.5, f3=-1.5,res1,res2;

res1=mod(f1,f2); // 5.1478

//res1=sgrt(f1*f1+f2*f2);

res2=mod(f1,f3); } // 4.743

//res2=sgrt(f1*f1+f3*f3); }

В ВС31 для inline-функции принято: 1) функция не должна быть рекурсивной; 2) функция не должна содержать операторов for, while, do, switch, goto. В этих случаях компилятор выдает предупреждение, и функция будет трактоваться как обычная.

Пример. Функция вводит символы, пока не введется ’q’. Функция рекурсивная, поэтому не может быть реализована как inline-функция.

inline void str() // Функции будет определена как обычная

{char b; if(cin>>b&&b!='q') str();}

1.8 Функции, возвращающие указатель

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

Пример. Функция возвращает адрес элемента массива, значение которого равно нулю. В программе это значение заменяется на 1.

#include <stdio.h>

int *func(int ,int []); //прототип функции

Void main()

{const N=5;

int *b,arr[N]={3,0,7,0,9}, n=0;

if((b=func(N,arr))!=NULL) // вызов функции

{n++; *b=1;

printf("*b=%d b=%p\n",*b,b);}

printf("выполнено замен %d \n",n);}

int *func(int n,int a[]) // Определение функции

{for (int i=0;i<n;i++)

if(a[i]==0) return &a[i];

return NULL;}

На экран выведется:

*b=1 b=8ff2:0FF2

*b=1 b=8ff2:0FF8

выполнено замен =2

1.9 Функции и структуры

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

Пример. В функцию передается структура и указатель на структуру

#include <string.h>

#include <stdio.h>

struct STUD{char name[20];int age;};

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]