Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

КЭкзCPP / MultiDimArray

.doc
Скачиваний:
31
Добавлен:
23.02.2015
Размер:
52.74 Кб
Скачать

Многомерные массивы

Многомерные массивы – совокупность однотипных элементов, упорядоченных с помощью системы индексов, для каждого измерения указывается размер.

Например,

const int n=5, m=6;

int a[n][m]; //это можно рассматривать как массив из 5-ти элементов, каждый из которых есть массив из 6-ти целых элементов, т.е. вектор из 5-ти векторов, ещё говорят - матрица 5*6.

В памяти такой массив располагается в последовательных полях построчно

a[0][0]

. .

a[0][5]

a[1][0]

a[1][5]

a[4][0]

a[4][5]

float b[3][5][4];//-массив 3-х мерный : 3 матрицы 5*4

Элементы 1 матрицы

Элементы 2 матрицы

Элементы 3 матрицы

Правило размещения : элементы многомерного массива располагаются в таком порядке, что у них быстрее всего меняется последний индекс:

b[0][0][0], b[0][0][1] ,b[0][0][2], b[0][0][3], b[0][1][0],

b[0][1][1], b[0][1][2], b[0][1][3],…

Для type a[n][m];

Адрес( a[i][j])= Адрес(a)+(i*m + j)*sizeof( type ), т.е.

для вычисления адресного выражения a[i][j] транслятору необходимо знать второй размер m, а не первый n.

Связь между массивами и указателями распространяется и на двумерные массивы. a[i][j] означает то же самое, что *(*(a+i)+j):

a[i]-рассматривается транслятором как имя одномерного массива из m элементов

(адрес начала i-той строки), т.е. это указатель i-той строки

a[i][j] = *(a[i]+j) = *(*(a+i)+j).

(в соответствии с арифметикой указателей). Все следующие выражения правильны и обозначают одно и то же

a[i][j] *(a[i]+j) (*(a+i))[j]

Инициализация многомерного массива:

int x[][]={{1,1},{2,1},{0,1}}; //3 строки по 2 элемента в строке.

int x[3][2]={1,1,2,1,0,1};// элементы по строкам

Передача многомерного массива в функцию

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

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

Параметр – многомерный массив можно оформить так (например, для двумерного массива):

тип имя [n][m],

Из формулы для адреса элемента массива видно, что первый размер n транслятору не нужен, а второй m нужен (он задает кол-во элементов в строке), поэтому параметр массив двумерный будет выглядеть так: тип имя [][m].

Аналогично 3-х мерный: тип имя [][m][k].

Здесь m, k – размеры, заданные при описании.

//Property_matr.cpp

#include <iostream>

using namespace std;

// Проверка свойств матриц

const int n=6;

void rdmm(int& k,int a[][n]);

bool simm(int k,int a[][n]);

int main ()

{ int k,L=0,c;

int a [n][n];

do

{rdmm(k,a);

if (simm (k,a)){cout<<"\n simmetr";L++;}

cout<< "echo? (1-yes,0-no)";

cin>>c;

}

while (c!=0);

if (L==0) {cout<<"\n no matrix";}

return 0;

}

void rdmm(int& k,int a[][n])

{int i,j;

// чтение матрицы

cout<<"\n razmer <= "<<n;

cin>>k;

cout<<"\n el-ti \n";

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

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

cin>>a[i][j];

}

bool simm(int k,int a[][n])

{// проверка , явл. ли матрица симметрической.

int i,j;

bool p;

i=0; p=true;

while ((i<k-1)&& p)

{j=i+1;

while ((j<k)&& p)

{p=(a[i][j]==a[j][i]);

j++;

}

i++;

}

return p;

}

Создание динамической матрицы

int n,m;

cout<<"vvedite n,m ";

cin>>n>>m;

//лучше всего такой способ создания динамической матрицы:

int **q= new int * [n];

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

q[i]=new int [m];

//заполнение матрицы

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

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

{q[i][j]=j*10+i;

//cout<<setw(5)<<q[i][j];

}

cout<<'\n';}

for(int i=0;i<n;i++){delete[]q[i];}

delete []q;

return 0;

}

Рассмотрим два различных определения

int *massiv[4]; //массив указателей на объекты типа int

int (*ptr)[4]; //указатель ptr на массив из 4 элементов, каждый из которых – int

Далее возможно выделить память, например,

ptr=new int [3][4];

delete [] ptr;

ptr – не имя массива, а переменная, позволяющая перемещаться по массива элементам, значение этого указателя определяется при выделении памяти – new.

Можно, случайно забыть (потерять) адрес первого элемента массива.

Благодаря массиву указателей можно более эффективно расходовать память…

Например,

«Обычное» выделение памяти -

char list[][30] = {“rectangle”, ”circle”, ”segment”};

«рациональное» -

char *pointer [] = {“rectangle”, ”circle”, ”segment”};

Пример перестановки указателей на одномерные массивы

void main()

{ const int n=5;

const int m=7;

double array [n][m];

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

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

array[i][j]=n-i;

double *par[n];

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

par[i]=(double *)&array[i];

cout<<endl;

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

{cout<<endl;

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

cout<<"\t"<<par[i][j];

}

double si,sk;

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

{ si=0.0;

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

si+=par[i][j];

for(int k=i+1; k<n; k++)

{ sk=0.0;

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

sk+=par[k][j];

if(si>sk)

{ double* pa = par[i];

par[i]=par[k]; par[k]=pa;

double a = si; si=sk; sk= a;

}

}

}

cout<<endl;

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

{cout<<endl;

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

cout<<"\t"<<par[i][j];

}

}

Соседние файлы в папке КЭкзCPP