Массивы в качестве параметров процедур и функций

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

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

int function Max(int *a, int n)

{

int кожный покров,k;

m=a[0];

for(k=1; k

if (m a[k]) m=a[k];

return m;

}

Полностью эквивалентным есть вариант с применением математики указателей:

int function Max(int *a, int n)

{

int m,k;

m=*a;

for(k=1; k

if (m *(a+k) m=*(a+k);

return m;

}

Следующий пример демонстрирует сложение квадратных матриц с приведением адресов элементов двумерного массива к их одномерным аналогам:

void sum_mat(int *a,int *b, int *c, int n)

{ int j,k,m;

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

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

{

m=j*n+k;

*(c+m)=*(a+m) + *(b+m);

}

}

Представлення матриць та багатовимірних масивів

Особого типа данных матрица либо многомерный массив в Си нет, но, возможно применять массив элементов типа массив. К примеру, переменная a воображает матрицу размера 3?3 с вещественными элементами:

double a[3][3];

Элементы матрицы находятся в памяти последовательно по строчкам: сперва идут элементы строчка с индексом 0, после этого строки с индексом 1, в конце строчка с индексом 2 (в программировании отсчет индексов постоянно начинается с нуля, а не с единицы!). Наряду с этим выражение

a[i]

где i — целая переменная, является указателем на начальный элемент i-й строки и имеет тип double*.

Для обращения к элементу матрицы нужно записать его индексы в квадратных скобках, к примеру, выражение

a[i][j]

является элементом матрицы a в строчке с индексом i и столбце с индексом j. Элемент матрицы возможно применять в любом выражении как простую переменную (к примеру, возможно просматривать его значение либо присваивать новое).

Такая реализация матрицы эргономична и максимально действенна с позиций времени доступа к элементам. У нее лишь один значительный недочёт: так возможно реализовать лишь матрицу, размер которой известен заблаговременно. Язык Си не разрешает обрисовывать массивы переменного размера, размер массива должен быть известен до начала работы программы еще на стадии компиляции.

Пускай нужна матрица, размер которой определяется на протяжении работы программы. Тогда пространство под нее нужно захватывать в динамической памяти посредством функции malloc языка Си либо оператора new языка C++ (см. раздел 3.7.3). Наряду с этим в динамической памяти захватывается линейный массив и возвращается указатель на него. Разглядим вещественную матрицу размером m строчков на n столбцов. Захват памяти выполняется посредством функции malloc языка Си

double *a;

. . .

a = (double *) malloc(m * n * sizeof(double));

либо посредством оператора new языка C++:

double *a;

int m, n;

. . .

a = new double[m * n];

Наряду с этим считается, что элементы матрицы будут размешаться в массиве следующим образом: сперва идут элементы строчка с индексом 0, после этого элементы строчка с индексом 1 и т.д., последними идут элементы строчка с индексом m ? 1. Любая строка складывается из n элементов, следовательно, индекс элемента строчка i и столбца j в линейном массиве равен

i * n + j

(вправду, потому, что индексы начинаются с нуля, то i равняется количеству строчков, каковые необходимо пропустить, i * n — суммарное количество элементов в пропускаемых строчках; число j равняется смещению в последней строчка). Так, элементу матрицы в строчке i и столбце j соответствует выражение

a[i * n + j]

Данный метод представления матрицы эргономичен и действен. Его главное преимущество пребывает в том, что элементы матрицы сохраняются в постоянном отрезке памяти. Во-первых, это разрешает оптимизирующему компилятору преобразовывать текст программы, получая большого быстродействия; во-вторых, при исполнении программы максимально употребляется механизм кеш-памяти, сводящий к минимуму обращения к памяти и существенно ускоряющий работу программы.

В некоторых книгах по Си рекомендуется реализовывать матрицу как массив указателей на ее строки, наряду с этим память под каждую строчок захватывается раздельно в динамической памяти:

double **a; // Адрес массива указателей

int m, n; // Размеры матрицы: m строчков, n столбцов

int i;

. . .

// Захватывается память под массив указателей

a = (double **) malloc(m * sizeof(double *));

Передача параметров в функцию по указателю c++. Передача указателя в функцию си. Урок #48

Похожие статьи:

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Adblock
detector