Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CИ-часть3студ.doc
Скачиваний:
12
Добавлен:
09.02.2015
Размер:
196.1 Кб
Скачать

6.4.Передача массивов в качестве параметров

При использовании массивов в качестве параметра в функцию передается указатель (адрес) на его первый элемент. Таким образом, массив всегда передается по адресу. Помимо собственно массива в функцию надо передавать и фактическое количество элементов массива. Формальный параметр функции, являющийся массивом, можно объявлять как тип элементов *a или как тип элементов a[]. Первая форма в явном виде выражает тот факт, что параметр является указателем, а вторая форма более наглядно показывает, что параметр является массивом. Во втором случае нет необходимости указывать количество элементов, т.к. в соответствии с указанным типом элементов транслятор сам вычисляет адрес каждого элемента массива, а на программисте лежит ответственность обрабатывать столько элементов, сколько их фактически хранится в массиве.

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

// запоминание отрицательных элементов

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

void soxran(float *a,int n,float b[],int *k);

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

{ const int nn=25;

float a[nn],b[nn];

int m,l;

printf("wwedite kol-wo elementow\n");

scanf("%d",&m);

printf("\n wwedite elementi massiwa\n");

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

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

soxran(a,m,b,&l);

if (l==0) printf("\notrizatelnix elementow net");

else

{printf("\n massiw otrizatelnix:\n");

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

printf("%6.2f ",b[i]);

}

getch();

return 0;

}

void soxran(float *a,int n,float b[],int *k)

{*k=0;

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

if (a[i]<0)

{b[*k]=a[i];

(*k)++;

}

}

При передаче многомерных массивов в функцию можно использовать вторую форму объявления формального параметра массива, но при этом необходимо указывать количество элементов по каждому измерению, начиная со второго (для первого измерения это делать не обязательно). Количество элементов при этом лучше задавать с помощью глобальной константы, так как в этом случае при изменении максимального количества элементов достаточно будет изменить значение этой константы, располагаемой в начале программы, и не надо вносить изменения в другие места программы. Это улучшает стиль программирования. Например,

const int mm=10,nn=20;

void f1(float a[][mm][nn],int k,int l, int m, float *s);

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

// передача в функцию трехмерного массива

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

const int nn=5,ll=12;

void sum(float a[][ll][nn],int m,int l,int n,float *s);

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

{ const int mm=15;

float a[mm][ll][nn],s;

int m,l,n;

printf("wwedite kol-wo elementow po trem ismerenijam\n");

scanf("%d%d%d",&m,&l,&n);

printf("\n wwedite elementi massiwa\n");

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

for (int j=0;j<l;j++)

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

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

sum(a,m,l,n,&s);

printf("\n summa=%6.2f",s);

getch();

return 0;

}

void sum(float a[][ll][nn],int m,int l,int n,float *s)

{*s=0;

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

for(int j=0;j<l;j++)

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

(*s)+=a[i][j][k];

}

Объявить формальный параметр - двумерный массив можно и так:

void f2(float (*a)[nn],…);

В приведенном объявлении функции f2 сообщается, что первый параметр является указателем на массив из nn элементов (nn – заранее объявленная глобальная константа). Скобки в этой записи обязательны, так как без скобок запись float *a[nn] означает массив из nn указателей. В этом случае фактически работа ведется с указателем на строку матрицы с известным заранее количеством элементов в строке, что также позволяет транслятору правильно вычислять адреса элементов матрицы. Приводимая программа вычисляет среднее арифметическое всех элементов матрицы и среднее геометрическое модулей ее элементов.

// формальный параметр - указатель на массив

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "math.h"

const int nn=12;

void sum(float (*a)[nn],int m,int n,float *sr,float *sg);

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

{ const int mm=15;

float a[mm][nn],sa,sg;

int m,n;

printf("wwedite kol-wo elementow po dwum ismerenijam\n");

scanf("%d%d",&m,&n);

printf("\n wwedite elementi matrizi\n");

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

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

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

sum(a,m,n,&sa,&sg);

printf("\n srednee arifm=%6.2f srednee geom=%6.2f",sa,sg);

getch();

return 0;

}

void sum(float (*a)[nn],int m,int n,float *sr,float *sg)

{*sr=0;

*sg=1;

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

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

{(*sr)+=a[i][j];

(*sg)*=a[i][j];

}

(*sr)/=(m*n);

*sg=pow(fabs(*sg),(float)1/(m*n));

}

Третий вариант объявления формального параметра – многомерного массива состоит в том, что используется фактический способ размещения элементов массива в памяти ЭВМ. Поскольку память ЭВМ – линейная структура, то все элементы многомерных массивов хранятся подряд друг за другом. (Массив с любым количеством измерений представляется как одномерный.) Программист в этом случае должен сам в программе организовать вычисление адреса элемента массива. При этом необходимо знать способ хранения массивов при использовании конкретного языка программирования. Язык C предусматривает, что элементы массивов хранятся таким образом, что быстрее всего изменяется последний индекс элементов (в частности, матрицы хранятся по строкам).

Для вычисления адреса элемента матрицы надо знать индексы элемента, а также максимальное количество элементов в строке (количество столбцов, заданное при объявлении массива.

Индекс элемента матрицы с индексами i и j в одномерном массиве, например, int a[1000], вычисляется по формуле i*nmax+j, где nmax -максимальное количество столбцов матрицы, а его адрес будет равен a+i*nmax+j.

В примере находится сумма двух матриц.

//нахождение суммы двух матриц

//матрица рассматривается как одномерный массив

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include "math.h"

void summatr(float *a,float *b,float *c,int m,int n,int nn);

void pech(float *a,int m,int n,int nn);

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

{ const int mm=15,nn=12;

float a[mm][nn],b[mm][nn],c[mm][nn];

int m,n;

printf("wwedite kol-wo elementow po dwum ismerenijam\n");

scanf("%d%d",&m,&n);

printf("\n wwedite elementi matrizi A \n");

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

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

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

printf("\n wwedite elementi matrizi B \n");

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

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

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

summatr(&a[0][0],&b[0][0],&c[0][0],m,n,nn);

printf("\n matriza A\n");

pech(&a[0][0],m,n,nn);

printf("\n matriza B\n");

pech(&b[0][0],m,n,nn);

printf("\n matriza C\n");

pech(&c[0][0],m,n,nn);

getch();

return 0;

}

void summatr(float *a,float *b,float *c,int m,int n,int nn)

{

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

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

c[i*nn+j]=a[i*nn+j]+b[i*nn+j];

}

void pech(float *a,int m,int n,int nn)

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

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

printf("%6.2f ",a[i*nn+j]);

printf("\n");

}

  1. }

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

Можно предложить еще один способ объявления формальных параметров - массивов, предусматривающий использование оператора typedef (см. [2] раздел 5.5).. С его помощью вводится в рассмотрение новый тип данных – двумерный массив. Причем можно объявить матрицу сразу как двумерный массив, а можно объявить как одномерный массив, состоящий из одномерных массивов. Следующая программа демонстрирует способ объявления типа двумерного массива с использованием оператора typedef. Здесь требуется объявить две глобальные константы, задающие максимальное количество строк и столбцов. Программа с помощью функции умножает каждый элемент матрицы на дробную часть элемента.

//умножение элементов матрицы на дробную часть

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

const int mmax=12, nmax=14;

typedef float tmatr[mmax][nmax];

void fun(tmatr a,int m,int n);

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

{

tmatr b;

int m,n;

printf("wwedite rasmeri m i n");

scanf("%d%d",&m,&n);

printf("\n wwedite matrizu \n");

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

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

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

printf("\n matriza\n");

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

{

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

printf("%6.2f ",b[i][j]);

printf("\n");

}

fun(b,m,n);

printf("\n matriza\n");

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

{

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

printf("%6.2f ",b[i][j]);

printf("\n");

}

getch();

return 0;

}

void fun(tmatr a,int m,int n)

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

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

a[i][j]*=(a[i][j]-(int)a[i][j]);

}

Объявление типа двумерного массива tmatr как одномерного, состоящего из одномерных массивов типа tv, можно выполнить так:

typedef float tv[nmax];

typedef tv tmatr[mmax];

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