Передача многомерных массивов в функции
При передаче многомерных массивов, как и для одномерных, все размерности должны передаваться в качестве параметров.
Существует несколько способов передачи многом. массивов в функцию:
1. С помощью указателя. Синтаксис объявление и определения функции такой же как и при передачи одномерных массивов. При вызове функции передаётся адрес первого элемента массива. Внутри функции массив интерпретируется как одномерный, а его индекс пересчитывается в программе.
В приведенном ниже примере с помощью функции находится максимальный элемент, а также их расположение в двух двумерных массивов. Размерность массива b известна на этапе компиляции, под массив а память выделяется динамически:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void out_matr(float *a,int nstr, int nstb);
float max(float *a, int nstr, int nstb, int &n, int &m);
int main(){
float b[3][3] = {{2, 2,5}, {4,0, 7},{3,2,6}};
int n1,m1;
n1=m1=0;
printf("B:\n");
out_matr(&b[0][0],3,3);
printf("Max B = %f ", max(&b[0][0], 3, 3,n1,m1));
printf("in %d str and %d stb\n",n1+1,m1+1);
int i, j, nstr, nstb;
printf("Введите количество строк и столбцов: \n");
scanf("%d%d", &nstr, &nstb);
float *a = new float[nstb*nstr];
for (i = 0; i<nstr; i++)
for (j = 0; j<nstb; j++)
a[i * nstb + j]=-10+20*float(rand())/RAND_MAX;
printf("A:\n");
out_matr(a,nstr,nstb);
printf("Max B = %f ", max(a, nstr, nstb,n1,m1),n1+1,m1+1);
printf("in %d str and %d stb\n", n1+1,m1+1);
return 0;}
void out_matr( float *a,int nstr, int nstb)
{int i, j;
for (i=0;i<nstr;i++)
{for (j=0;j<nstb;j++)
printf("%5.2f ",a[i*nstb+j]);
printf("\n");
}}
float max(float *a, int nstr, int nstb, int &n, int &m)
{int i, j;
float s=a[0];
n=m=0;
for (i=0;i<nstr;i++)
for (j=0;j<nstb;j++)
if (a[i*nstb+j]>s)
{s= a[i*nstb+j]; n=i;m=j;}
return s;}
2 способ. используется для того чтобы работать с двумерным массивом естественным образом. В этом случае в определении функции применяется указатель на указатель(см. динамич. многом. массивы.)
Задача. Найти произведение матриц.
#include <stdio.h>
#include <conio.h>
void in_matr(int **a,int nstr,int nstb);
void out_matr(int **a,int nstr,int nstb);
void proizv(int **a, int **b,int **c, int , int ,int);
int main(){
int i, j, n, m,k;
printf("Введите количество строк и столбцов: \n");
scanf("%d%d", &n, &m);
int **a = new int*[n];
for (i = 0; i<n; i++) a[i] = new int [m];
in_matr(a,n,m);
printf("Введите количество столбцов(строк =%d): \n",m);
scanf("%d", &k);
int **b=new int *[m];
for (i = 0; i<m; i++) b[i] = new int [k];
int **c=new int *[n];
for (i = 0; i<n; i++) c[i] = new int [k];
in_matr(b,m,k);
printf("A:\n");
out_matr(a,n,m);
printf("B:\n");
out_matr(b,m,k);
proizv(a,b,c,n,m,k);
printf("A*B:\n");
out_matr(c,n,k);
getche();
return 0;}
void in_matr(int **a,int nstr,int nstb)
{ int i,j;
for (i = 0; i<nstr; i++)
for (j = 0; j<nstb; j++)
scanf("%d", &a[i][j]);
}
void out_matr(int **a,int nstr,int nstb)
{ int i,j;
for (i = 0; i<nstr; i++)
{for (j = 0; j<nstb; j++)
printf("%d ", a[i][j]);
printf("\n");}
}
void proizv(int **a, int **b,int **c, int n, int m,int l)
{int i, j,k, s=0;
for (i=0;i<n;i++)
for (j=0;j<l;j++)
{c[i][j]=0;
for(k=0;k<m;k++)
c[i][j]+=a[i][k]*b[k][j];
}}
В этом случае память выделяется в два этапа: сначала под столбец указателей на строки матрицы, а затем в цикле под каждую строку, как показано на рис. 1.10. Освобождение памяти должно выполняться в обратном порядке.
Шаблоны функций
Многие алгоритмы не зависят от типов данных, с которыми они работают (классический пример — сортировка). Естественно желание параметризовать алгоритм таким образом, чтобы его можно было использовать для различных типов данных.
В C++ есть мощное средство параметризации — шаблоны. С помощью шаблона функции можно определить алгоритм, который будет применяться к данным различных типов, а конкретный тип данных передается функции в виде параметра на этапе компиляции. Компилятор автоматически генерирует правильный код, соответствующий переданному типу. Таким образом, создается функция, которая автоматически перегружает сама себя и при этом не содержит накладных расходов, связанных с параметризацией.
Формат простейшей функции-шаблона:
template <c1ass Type> заголовок
{
/* тело функции */ }
Вместо слова Type может использоваться произвольное имя.
В общем случае шаблон функции может содержать несколько параметров, каждый из которых может быть не только типом, но и просто переменной, например:
template<c1ass A. class В, int C> void f(){ ... } ' ^
Например, функция, сортирующая методом выбора (он был рассмотрен на с. 59) массив из п элементов любого типа, в виде шаблона может выглядеть так:
#include<iostream.h>
template <class Type> void sort_vybor(Type *b, int n);
int main()
{
const int n=20;
int i, b[n];
for (i= 0; i<n-1; i++) cin>>b[i];
sort_vybor(b, n);
for (i= 0; i<п-1; i++) cout<<b[i]<<’ ‘;
cout<<’\n’;
double a[]={3,2,5,1,7};
sort_vybor(a, 5);
for (i= 0; i<n-1; i++) cout<<a[i]<<’ ‘;
cout<<’\n’;
return 0;
}
template <class Type> void sort_vybor(Type *b. int n)
{
Type а; //буферная переменная для обмена элементов
for (int i= 0; i<п-1; i++)
{ int imin = i;
for (int j = i + 1;j<n; j++)
if (b[j] < b[imin]) imin= j;
a=b[i]; b[i]=b[imin]; b[imin]=a
}
}
Дата добавления: 2017-01-13; просмотров: 1037;