Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие_С++.docx
Скачиваний:
88
Добавлен:
11.04.2015
Размер:
842.63 Кб
Скачать

Возвращение результатов

Результат работы функции возвращается в точку вызова с помощью оператора

return [выражение];

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

Теория создания функций, рассмотренная в данном параграфе, является базовой и будет достаточной для начинающих программистов. Для более глубоко изучения данного вопроса следует обратиться, например [4]. Но, даже изучив теорию в таком объеме, у нас есть возможность научить вас собирать собственные библиотечные файлы.

Примеры программирования задач с использованием подпрограмм Задача 1

Даны два вектора: = {хi}; i =и={yi};i =.

Вычислить значение: D = , где ;;

тх, ту - максимальные компоненты векторов и соответственно;

sx, sy - средние значения компонент векторов и соответственно.

Решение:

#include "stdafx.h"

#include <math.h>

float Mod_Otk(float *a, int n) /* типизированная функция для нахождения максимального компонента и среднего значения в любом массиве */

{

float maxi, sa, Da; //описание локальных переменных

int i;

maxi =-10000; 

sa=0;

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

{

if (a[i]>maxi) maxi= a[i];

sa += a[i];

}

sa = sa/n;

Da= fabs(maxi - sa);

return Da;

}

void main()

{ float X[10],Y[10];

int i;

float Dx, Dy, D;

printf("Bведитe массив X:\n");

for (i =0;i<8;i++)

scanf("%f",&X[i]);

printf("Bведитe массив Y:\n");

for (i =0;i<10;i++)

scanf("%f",&Y[i]);

Dx = Mod_Otk(X, 8);//вызов функции Mod_Otk для массива X

Dy = Mod_Otk(Y,10);//вызов функции Mod_Otk для массива Y

D = Dx/Dy;

printf("D=%f\n",D);

}

Задача 2

Даны две матрицы: А = {a i j }5x6 и В = {b i j}4x7.

Вычислить разность: С = КА - KB, где КА и KB - количество положительных элементов в матрицах А и В соответственно.

#include "stdafx.h"

int CP(float D[7][7], int m, int n) /*типизированная функция для подсчета количества положительных элементов в любой матрице */

{ int i, j, KD;

KD=0;// инициализация счетчика

for (i=0;i<m;i++)

for (j=0;j<n;j++)

if (D[i][j]>0) KD ++; /*добавление в счетчик единицы, если элемент матрицы окажется >0 */

return KD; // возвращение результата в точку вызова

}

int main()

{

float A[7][7], B[7][7];

int i,j, C;

printf("Введите матрицу А\n");

for (i=0;i<5;i++)

for (j=0;j<6;j++)

scanf("%f",&A[i][j]);

printf("Введите матрицу B\n");

for (i=0;i<4;i++)

for (j=0;j<7;j++)

scanf("%f",&B[i][j]);

C= CP(A, 5,6)- CP(B, 4, 7); //вызовы функции СР

printf("C=%d\n", C);

return 0;

}

Задача 3

На плоскости декартовыми координатами заданы 10 точек:

{x1,y1},{x2,y2}, ...,{х1010}.

Вывести полярные координаты точки, имеющей наибольший полярный радиус. Вычисление полярных координат одной точки оформить подпрограммой. Расчетные формулы для вычисления полярных координат следующие:

, где а и b -декартовы координаты точки.

Решение:

#include "stdafx.h"

#include<math.h>

void PK(float a, float b, float *ro, float *fi)

/* безтиповая функция для расчета полярных координат точки */

{

*ro = sqrt(a*a + b*b);

*fi = atan(b/a);

}

int main()

{

float X[10], Y[10]; // масcивы для декартовых координат точек

float R[10], F[10]; // масcивы для полярных координат точек

int i, N;

float maxR;

printf("Введите абсциссы 10 точек\n");

for (i=0;i<10;i++) scanf("%f",&X[i]);

printf(" Введите ординаты 10 точек\n");

for (i=0;i<10;i++) scanf("%f",&Y[i]);

maxR = 0;

for (i=0;i<10;i++)

{

PK(X[i],Y[i],&R[i],&F[i]);

if (R[i]>maxR) // поиск максимального радиуса

{

maxR =R[i];

N=i; /*запоминаем номер точки, радиус которой больше, чем у предыдущих */

}

}

printf("romax=%f fimax=%f\n", R[N],F[N]);/* вывод полярных координат точки с номером N */

return 0;

}

Задача 4

Для заданных квадратных матриц: A = {a i j}3x3 и В = {bi j}4х4 вычислить симметричные им матрицы по правилу:

, x- матрица , симметричная матрице y.

Решение:

#include "stdafx.h"

void SM(float Y[4][4], int n, float X[4][4])/*безтиповая функция вычисления симметричной матрицы X из исходной матрицы Y */

{

int i,j;

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

for (j=i;j<n;j++)

{

X[i][j]=(Y[i][j] + Y[j][i])/2;

X[j][i] =X[i][j];

}

}

void VIVOD(float Y[4][4], int n)//функция вывода матрицы

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

{for (j=0;j<n;j++) printf("%8.2f",Y[i][j]);

printf("\n");

}

}

void main()

{

float A[4][4], B[4][4], C[4][4], D[4][4];

int i, j;

printf("Введите матрицу А\n");

for (i=0;i<3;i++)

for (j=0;j<3;j++) scanf("%f",&A[i][j]);

printf("Введите матрицу B\n");

for (i=0;i<4;i++)

for (j=0;j<4;j++) scanf("%f",&B[i][j]);

SM(A, 3,C); // обращение к функции SM для матрицы A

SM(B, 4, D); //обращение к функции SM для матрицы B

printf("Симметричная матрица С\n");

VIVOD(C,3);

printf("Симметричная матрица D\n");

VIVOD(D,4);

}

Перегрузка функций в С++

Перегруженная функция – это функция, которая позволяет при обращении к себе варьировать типы передаваемых параметров. Цель перегрузки состоит в том, чтобы функция с одним и тем же именем возвращала разного типа значение при обращении к ней с различными типами фактических параметров. Рассмотрим этот механизм на примере некоторой абстрактной функции с именем SUM. Допустим, мы имеем три варианта функции SUM.

float SUM (float a, float b);

//принимает два вещественных аргумента и возвращает результат ввиде вещественного числа

double SUM (double a, double b);

//принимает два аргумента вещественного длинного типа и возвращает результат ввиде вещественного длинного числа

complex SUM (complex a, complex b);

//принимает два аргумента комплексного типа и возвращает результат ввиде комплексного числа

Компилятор определит, какую именно функцию с именем SUM надо вызвать по типу передаваемых ей параметров.

Наполним функцию SUM банальным алгоритмом вычисления суммы двух чисел.

#include "stdafx.h"

#define complex struct compl

complex

{double x,y;};

complex SUM (complex a, complex b)

{complex c;

c.x=a.x+b.x;

c.y=a.y+b.y;

return c;

}

float SUM (float a, float b)

{float c;

c=a+b;

return c;

}

double SUM (double a, double b)

{ double c;

c=a+b;

return c;

}

int _tmain(int argc, _TCHAR* argv[])

{complex z,m,n;

float a=4.5,b=6.5;

z.x=5; z.y=6;

m.x=7;m.y=8;

n= SUM (z,m); //вызов функции SUM для комплексных параметров

printf("%lf+i%lf\n",n.x,n.y);

float d= SUM (a,b); //вызов функции SUM для вещественных параметров

printf("d=%f\n",d);

float d2= SUM (10,35); //неоднозначный вызов функции SUM

printf("d2=%f\n",d2);

return 0;

}

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

По типам фактических параметров компилятор определяет, какую именно функцию требуется вызвать. Этот процесс называется разрешением перегрузки (перевод английского слова resolution в смысле «уточнение»). Тип возвращаемого функцией значения в разрешении не участвует. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать функцию с наиболее подходящими аргументами или выдать сообщение, если такой не найдется. Если точного соответствия не найдено, выполняется преобразование типов параметров по общим правилам, например char в int; int во float, float в double; и т.п. Если соответствие может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке. В нашем примере это продемонстрировано вызовом третьим, когда в функцию SUM передаются в качестве параметров два целых числа 10 и 35. Эти параметры могут быть преобразованы как в тип float, так и в тип double, что и вызовет возникновение ошибочной неоднозначности.

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

• Перегруженные функции должны находиться в одной области видимости,

иначе произойдет сокрытие аналогично тому, как это происходит с одинаковыми именами переменных во вложенных блоках.

• Перегруженные функции могут иметь параметры по умолчанию, при этом

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

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

• Функции не могут быть перегружены, если описание их параметров отличается только модификатором const (например, int и const int ), или использованием ссылки (например, int и int&).

Более подробную информацию о перегруженных функциях см. в [2].