Указатели и двумерные массивы


Двумерные массивы в языке С++ устроены значительно сложнее одномерных. И если одномерный массив – это область памяти с последовательно идущими элементами, то двумерный массив – это массив одномерных массивов.

Двумерные массивы в языке C++ – это массивы массивов, т.е. массивы, элементами которых, в свою очередь, являются одномерные массивы.

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

Массивы указателей

Как и любые другие переменные, указатели могут быть объединены в массивы. Массив указателей фиксированных размеров может быть задан следующим образом:

тип * имя_массива[размер];

Например, массив указателей на данные типа int объявляется следующим образом:

int * p[10];

Здесь каждый элемент массива p содержит указатель на целочисленное значение, т.е. элементы этого массива могут содержать только значения, которые представляют собой адреса переменных, массивов типа int.

По аналогии с обычными указателями, i-ый элемент объявленного таким образом массива указателей p[i] можно проинициализировать, например, одним из следующих способов:

· с помощью адреса переменной: int x; p[i] = &x;

· с помощью объявленного указателя: int * q = &x; p[i] = q;

· с помощью адреса массива: int a[5]; p[i] = a;

Указатели на указатели

В С++ можно создавать указатели на другие указатели, которые, в свою очередь, содержат адреса реальных переменных, т.е. можно создавать указатели на указатели.

Чтобы объявить в программе указатель, который будет хранить адрес другого указателя, нужно просто удвоить число звёздочек в объявлении:

тип ** имя_указателя;

Например: int ** p;

Объявленный таким образом указатель p может содержать адрес указателя на переменную типа int. Адрес указателя может быть получен с помощью унарной операции адреса (&). Например:

int x = 10;

int *p, **q;

p = &x; q = &p;

cout<<x<<" "<<*p<<" "<<**q<<endl; // 10 10 10

После выполнения этих операторов указатель qбудет содержать адрес указателя p, содержащего адрес переменной x со значением 10.

Указатель на указатель – это переменная, содержащая адрес другого указателя.

Язык С++ позволяет объявить указатель на указатель на указатель и так далее. Для этого при объявлении перед указателем следует поставить нужное количество звездочек.

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

При объявлении двумерных массивов,например, при выполнении объявления int matr[4][3]; происходит следующее:

· создаётся указатель matr, который определяет в памяти местоположение первого элемента массива (с индексами [0][0]) и, кроме того, является указателем на массив из четырех указателей matr[4];

· каждый из этих четырех указателей matr[i]содержит адрес одномерного массива, представляющего собой i-строку двумерного массива и состоящего из трёх элементов типа int;

· каждый указатель matr[i]позволяет обратиться к соответствующей i-ой строке матрицы.

Доступ к элементам массива указателей осуществляется с указанием одного индексного выражения в форме

matr[i] или эквивалентного ему *(matr+i).

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

matr[i][j]

или эквивалентных ему

*(matr[i]+j) и *(*(matr+i)+j)

Следует учитывать, что с точки зрения синтаксиса языка C++ указатель matr и указатели matr[0], matr[1], matr[2],matr[3] являются константами, и их значения нельзя изменять во время выполнения программы. Поэтому, например, переставить местами строки матрицы с помощью указателей matr[i]мы не сможем. Но сможем, например, передавать строки матрицы в функцию, используя массив указателей matr[4],что и продемонстрируем в следующем примере.

// Пример 8.5. В данной целочисленной матрице matr[n][m] найти

// сумму элементов в каждой строке, используя функцию нахождения

// суммы элементов в одномерном массиве.

#include <iostream>

using namespace std;

const int DIM1 = 20, DIM2 = 20;

int Summa(int *ar, int size){

int sum = 0;

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

sum = sum + ar[i];

return sum;

}

int main(){

int matr[DIM1][DIM2], s[DIM1];

int n, m, i, j;

cout<<"Vvedi n, m: "; cin>>n>>m;

srand(n+m);

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

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

matr[i][j] = rand() % 25 - 10;

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

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

cout.width(4); cout<<matr[i][j];

}

cout<<endl;

}

cout<<"\t\tSum elementov strok== "<<endl;

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

s[i] = Summa(matr[i], m); // вызов функции Summa()

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

cout<<'\t'<<s[i];

cout<<endl;

system("pause");

}

Если же мы хотим использовать массив указателей для перестановки строк матрицы matr, то следует вначале создать массив указателей p следующим образом:

int * p[4];

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

p[i] = matr[i];

И затем для перестановки элементов строк матрицы достаточно поменять местами указатели на строки в массиве указателей p.

Доступ же к элементам двумерного массива может осуществляться как с помощью индексации его имени (как показано выше), так и с помощью указателей:

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

// Пример 8.6. В данной целочисленной матрице a[n][m] переставить

// местами 1 и 2 строки, используя массив указателей на строки.

#include <iostream>

using namespace std;

const int DIM1 = 20, DIM2 = 20;

int main(){

int a[DIM1][DIM2];

int * p[DIM1]; // массив указателей p

int n, m;

cout<<"Vvedi n, m: "; cin>>n>>m;

srand(n+m);

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

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

a[i][j] = rand() % 25 - 10;

for(int i = 0; i < n; i++) // инициализация массива указателей

p[i] = a[i]; // или p[i] = &a[i][0]; или p[i] = (int*)&a[i];

 

 

cout<<"Matrix isxodnaya=="<<endl;

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

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

cout.width(5);

cout<<p[i][j];

}

cout<<endl;

}

int * x;

x = p[0]; p[0] = p[1]; p[1] = x; // перестановка 1 и 2строк

/* x=a[0];

a[0]=a[1]; // ошибка!!!! Имя одном. массива – const-указатель.

a[1]= x;

*/

cout<<endl<<"Matrix posle perestanovki== "<<endl;

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

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

cout.width(5);

cout<<*(p[i] + j);

}

cout<<endl;

}

cout<<endl<<"Matrix isxodnaya== "<<endl;

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

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

cout.width(5);

cout<<a[i][j];

}

cout<<endl;

}

system("pause");

}



Дата добавления: 2022-05-27; просмотров: 60;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.015 сек.