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

Void main()

{

inta,b,c,d,e,f,h,g;

double y;

cout<<”\nVvedi 8 celih chisel”);

cin>>a>>b>>c>>d>>e>>f>>h>>g;

y=sr(6,h,f,g,c,d,e);

cout<<”\Sredneearifm=”<<y;

y=sr(8,a,b,c,d,e,f,h,g);

cout<<”\Sredneearifm=”<<y;

}

doublesr(int k,…)

{

void *p;

p=&k; //адресk

( (int *)p)++; //переход на первый элемент списка переменной длины

int h=0, g=k;

while (k)

{

h+=*((int *)p);

((int *)p)++;

k--;

}

return(double)h/g;

}

Пример функции с переменным числом аргументов использующих второй способ реализации функции.

int sum(int k, …)

{

int s=0, *p;

p=&k;

p++;

for (int i=0; i<k; i++)

{S+=*p++; }

returns;

}

3-йспособ. Вычислить сумму элементов списка оканчивающегося на 0.

#include <iostream.h>

#include <stdarg.h>

void sum(char *soob, …)

{

int s=0, arg;

va_list a;

va_start (a, soob);

while (arg=va_arg(a, int))

s+=arg;

va_end;

cout<<soob<<s;

}

Void main()

{

sum(“summa 5+6+7+8+9+10=”,5,6,7,8,9,10,0);

}

  1. Рекурсивные вычисления выполняются повторным вхождением в одну и ту же функцию. Каждое вхождение имеет свою память для внутренних переменных и не зависит от других вхождений. Эта память выделяется в стеке.

Недостатки рекурсии:

- потеря времени на вызов функции и передачу её аргументов.

- возможные превышения объема памяти выделенной под стек.

Достоинства рекурсии:

- рекурсия позволяет создать достаточно простые и эффективные алгоритмы для некоторых задач.

- любой алгоритм можно представить в рекурсивной и не рекурсивной форме. Вопрос только в выборе наиболее эффективного алгоритма.

Основное правило создания рекурсивной функции: необходимо правильно реализовать выход из рекурсии.

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

Вычисление n!

#include <stdio.h>

double fact(double n)

{

if (n<=0) return 1;

else return n*fact(n-1);

}

Void main ()

{

doubler,n;

printf(“\n vvediceloe n->”);

scanf(“%d”,&n);

r=fact(n);

printf(“\n%d!=%10lf”,r);

}

Уточнить значение корня уравнения f(x)=0 на отрезке [a,b] с точностью Ɛ

Методом деления отрезка пополам.

f(a)*f(b)<0

1)x=(a+b)/2;

2)еслиf(a)*f(b)<0

то выбираем отрезок [a,x] =>b=x

иначе если f(x)*f(b)<0

то выбираем [x,b] =>a=x

иначе x–корень

3)если |a-b|<= Ɛ, то x-корень

doublepopolam(double a, double b, double eps, double (*f)(double x))

{

double x;

x=a(a+b)/2;

if (fabs(a-b)<=eps) return x;

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

else if ((*f)(x)*(*f)(b)<0) a=x;

else return x;

x=popolam(a, b, eps, f);

}

//x+sinx=0

double fin(double x);

{

returnx+sin(x);

}

Void main()

{

doublea,b,c,x;

printf(“\n vvedi [a,b] I tochnost c\n”);

scanf(“%lf%lf%lf”,&a,&b,&c);

x=popolam(a,b,c,fun);

printf(“\n x=%10.3lf”,x);

}

  1. Использование нескольких функций с одним и тем же именем в одной и той же программе, но с разными типами аргументов и/или типами функций называется перегрузкой функции. А сами функции называются перегруженными. Выбор нужной функции осуществляется компилятором по типу фактических аргументов при вызове функции.

int max(int , int);

char* max(char*, char*);

int max(int, char*);

int max(char*, char*);

void f1(int a, int b, char *c, char *d)

{

char *s;

s=max(c,d);

int k=max(c,d);

cout<<max(a,b)<<s<<max(a,c)<<max(b,d);

}

При вызове функции компилятор выбирает функцию по типу соответствующих аргументов, если точного соответствия не найдено, то происходит преобразование. Затем происходит поиск нужной функции, если соответствие не найдено или можно использовать более 1-й функции, то выдаётся сообщение об ошибке. Возникает ситуация неоднозначности, такие ошибки устраняет программист.

  1. Шаблоны функции

Многие алгоритмы не зависят от типов данных с которыми они работают. Хотелось бы такой алгоритм записать в функцию, которую можно было использовать для различных типов данных. Т.е. в качестве параметра задавать тип. Для этой цели в C++ используются шаблоны функций. Цель введения шаблонов функций – автоматизация создания функций, которые могут обрабатывать разнотипные данные. Для этой цели создаётся один шаблон функции,по которому автоматически, компилятор при вызове функции с определенными типами аргументов сам создаёт функцию. Параметром шаблона может быть тип возвращаемого значения и типы любых аргументов. Компилятор по вызовам функций, используя шаблон, генерирует правильный код функции соответствующий указанному типу аргументов при вызове. Т.о., созданная функция, которая автоматически перегружает сама себя.

Формат шаблона функции:

template<classtype1, classtype2, …>

//заголовок функции

{телоф-ции}

Пример template<classT>

T abs(T x)

{

return x<0 ? –x:x;

}

template<classA>

void swap(A* x, A* y)

{

A z;

z= *x;

*x=*y;

*y=z;

}

longk,d;

swap(&k,&d);

void swap(long *x, long *y)

{

longz;

--//--

}

Параметры шаблоны имеют ряд свойст1в:

1)имена параметров шаблонов должны быть уникальными

2)список параметров шаблонов не должен быть пустым.

3)при наличии нескольких параметров каждый начинается со слова class

4)в списке параметров шаблона не может быть одинаковых имен.

Шаблон функции, как и функция, имеет прототип.

#include <iostream.h>

Template <class a>

void sort (int n, a*X);

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