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

Void CorrArr(int * Arr, int Dim)

{

int i;

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

if(Arr[i]<1)

Arr[i]=0; //*(Arr+i)=0;

}

Void main(void)

{

int a[]={1,-2,-3,4};

CorrArr(a,4);

printf("%d %d\n",a[1],a[2}); //будет напечатано 0 0

}

Таким образом, массивы отличаются от других типов тем, что они не передаются и не могут передаваться по значению.

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

Можно передавать еще один параметр, задающий размер массива, как это было в вышеприведенном примере.

Сложнее обстоит дело с многомерными массивами. Рассмотрим функцию, работающую с двумерным массивом - матрицей.

Если размеры обоих индексов известны на этапе трансляции, то проблем нет:

Void print_arr(int m[3][4])

{

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

{

for (int j = 0; j<4; J++)

cout << ' ' << m[i][j];

cout << '\n';

}

}

Конечно, матрица по-прежнему передается как указатель, а размерности

используются компилятором для вычисления адреса элемента. Первая размерность

для вычисления адреса элемента не важна (почему??????), поэтому ее можно

передавать как параметр:

Void print_arr(int m[][4], int dim1)

{

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

{

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

cout << ' ' << m[i][j]; //*(*(m+i)+j) - j умножается на размер элемента,

//а он известен (размер int)

cout << '\n';

}

}

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

Самый сложный случай - когда надо передавать обе размерности, то есть наша функция должна работать с массивом произвольной размерности. Здесь "очевидное" решение просто непригодно:

Void print_arr(int m[][], int dim1, int dim2) // ошибка

{

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

{

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

cout << ' ' << m[i][j]; //*(*(m+i)+j) – компилятор не знает, на что нужно

//домножать i

cout << '\n';

}

}

Описание параметра как m[][] для компилятора недопустимо, поскольку ему для вычисления адреса элемента многомерного массива нужно знать вторую

размерность. Для решения этой проблемы предлагается следующий подход. Память,

занимаемая двухмерным массивом, интерпретируется как память, занимаемая

одномерным массивом. Так как двухмерный массив в одномерной памяти

располагается по строкам, то элементу двухмерного массива с индексами i и j,

соответствует элемент одномерного массива со значением индекса k=i*dim2+j. Значение к равняется количеству предшествующих элементов массива, а оно равно количеству элементов в предшествующих строках (i*dim2) плюс количество предшествующих элементов в текущей строке (j).

Поскольку в языке Си индексация начинается с 0, из i и j не требуется вычитать по единице. То есть мы проделываем те же вычисления, что и компилятор, когда он вычисляет смещение элемента многомерного массива относительно адреса начала этого массива.

Поэтому правильным решением будет:

#include <iostream.h>