Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Posobie_Cpp.doc
Скачиваний:
6
Добавлен:
20.11.2019
Размер:
603.14 Кб
Скачать

3.1.6. Динамические двумерные массивы.

В динамической области памяти можно создавать и многомерные массивы. Наиболее часто это приходитcя делать с двумерными массивами. Выше уже отмечалось «родство» одномерных массивов и указателей. В С++ двумерный массив можно интерпретировать как указатель на указатель. Ниже приводится фрагмент кода, с помощью которого выделяется память под массив из nrow строк и ncol столбцов:

int n=5;

int *a=new int[10]; // создаем одномерный массив а[10]

int nrow=7,ncol=10;

int **mass =new int *[nrow]; //массив указателей mass[nrow]

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

// элементу массива указателей присваивается участок памяти под

// строку двумерного массива:

mass[i]=new int [ncol];

// созданный двумерный массив далее можно использовать обычным образом

mass[1][2] = 13;

//Последовательное уничтожение двумерного массива…

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

delete[] mass[i];

delete[] mass;

3.1.7. Указатели, массивы и арифметика указателей.

Уже отмечалось, что имя массива является указателем на первый (нулевой) элемент массива. Следующий пример иллюстрирует это утверждение:

Int tacs[3];

tacs[0] = 43; // присваиваем значение нулевому элементу

*tacs = 2; // или так присваиваем новое значение нулевому элементу

*(tacs + 1) = 4; // присваиваем значение первому элементу

По видимому, нет необходимости обращаться к i-му элементу массива, используя выражение *(tacs + i) , а не tasc[i]. Однако знать о такой возможности следует.

Такой же принцип доступа к элементам массива сохраняется и для многомерных массивов. Так, доступ к элементу двумерного массива можно получить обычным способом: mass[i][j], а можно так: *(mass[i] + j) или *(* (mass +i)+j).

  • С++ позволяет решать одну и ту же задачу разными способами, иногда экзотичными. Старайтесь использовать наиболее простые для понимания решения.

С указателями можно выполнять следующие операции: разыменования (*), присваивания, сложение с константой, вычитание указателей, инкремента (++), декремента (--), приведения типов.

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

int *pint = new int [3]; // выделена память под массив из трех элементов

p++; // значение увеличивается на 4

Разность двух указателей дает число, равное разности адресов, деленное на размер типа, выраженное в байтах. Не допускается сложение указателей.

При использовании нескольких операций, следует помнить об их приоритете. Так выражение

*pint++ = 12;

следует понимать так

*pint = 12; pint++; // по адресу связанному с pint пишется значение 12

// затем значение pint увеличивается

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

(*pint)++; // значение по адресу pint увеличивается на единицу &&&&

Следующий фрагмент кода копирует элементы массива в другой массив1. Из возможных способов выбран тот, который иллюстрирует особенности арифметики указателей:

int a [100], b[100];

int *pa = a; // или int *pa = &a[0];

int *pb = b;

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

*pb++ = *pa++; // или b[i]=a[i];

Контрольные вопросы и задания.

1. Почему в приведенной ниже программе значение элемента массива p[2] становится неопределнным? Почему p[0] становится равным 2?

#include <iostream.h>

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