Динамические массивы
.pdfДинамические массивы. Работа с памятью.
Определение динамического массива.
Чтобы создать массив, размерность которого не определена внутри программы, используется оператор new (оператор динамического распределения
памяти) |
или присваивается указателю явный адрес: |
int n; |
//Выделена переменная для хранения размерности массива |
cin>>n; |
//Ввод размерности массива |
int *array=new int[n]; // Выделили память для переменной типа int и связали указатель array с этим участком памяти cout<<"Введите элементы массива: "; //Занесение данных в ячейки памяти отведенных для элементов массива
for (i=0; i<n; i++) cin>>array[i];
Освобождение памяти из под массива выполняется с помощью операции delete array.
Многомерные массивы
Специального типа многомерный массив в языке Си не существует, однако, возможно объявление массива массивов (т.е. массива элементами которого являются массивы) или массива массива массивов и т.д. Например:
double array_2d[100][20] ; //задаёт для переменной array_2d область памяти, в которой помещается 100 массивов по 20 элементов типа double.
int a[3][5]; //задаёт для переменной a область памяти, в которой помещается 3 массива по 5 элементов типа int (или задается матрица из 3 строк и 5
столбцов). Массив хранится по строкам в непрерывной области памяти: а00 а01 а02 а03 а04 а10 а11 а12 а13 а14 а20 а21 а22 а23 а24
|---0-я строка----|---1-я строка----|---2-я строка----|
Строки массива ничем не отделены друг от друга, т.е. прямоугольной матрицей двумерный массив является только в нашем воображении. В памяти сначала располагается одномерный массив a[0], представляющий собой нулевую строку массива a, затем - массив a[1], представляющий собой первую строку массива a, и т. д. Количество элементов в каждом из этих массивов равно длине строки, т. е. количеству столбцов в матрице. При просмотре массива от начала в первую очередь изменяется правый индекс (номер столбца).
Для доступа к отдельному элементу массива роименяется конструкция вида а[i][j], где i (номер строки) и j (номер столбца) – выражения целочисленного типа. Каждый индекс может изменяться от 0 до значения соответствующей размерности, уменьшенной на единицу.
В конструкции a[3][5] первый индекс всегда воспринимается как номер строки, второй – как номер столбца, независимо от имени массива. Обращение к элементам такого «двумерного» массива происходит аналогичным образом:
double х = array_2d[80][10]; array_2d[90][19] = 1.3е-10; if(a[2][3]<0) { a[2][3]=0;}
При описании массива можно задать начальные значения его элементов. Их записывают в фигурные скобки. Элементы массива инициализируются в порядке их расположения в памяти. Например оператор: int a[3][5]={1, 5, 2, 7, 9, 3, 3, 1, 1, 0, 7, 9, 0, 1, 2}; определяет матрицу со следующими значениями элементов: 1 5 2 7 9
3 3 1 1 0
7 9 0 1 2
Динамические двумерные массивы. Двумерные массивы также как и одномерные создаются в динамической области памяти с помощью операции new. Например:
int n; |
|
const int m=5; |
|
cin>>n; |
|
int(*a)[m]=new int [n][m]; |
// 1 |
int **b=(int**)new int[n][m]; |
// 2 |
В этом фрагменте показано два способа создания динамического массива. В операторе 1 адрес начала выделенного с помощью new участка памяти присваивается переменной а, определенной как указатель на массив из m элементов типа int. Именно такой тип значения возвращает в данном случае операция new. Скобки необходимы, поскольку без них конструкция интерпретировалась бы как массив указателей. Всего выделяется n элементов.
В операторе 2 адрес начала выделенного участка памяти присваивается переменной b, которая описана как "указатель на указатель int", поэтому перед присваиванием требуется выполнить преобразование типа.
Более универсальный и безопасный способ выделения памяти под двумерный массив, когда обе его размерности задаются на этапе выполнения программы, приведен ниже:
int nrow, ncol;
cout<<"Введите количество строк и столбцов :";
cin>>nrow>>ncol; |
|
int**a=new int *[nrow]; |
// 1 |
for(int i=0; i<nrow; i++) |
// 2 |
a[i] = new int [ncol]; |
// 3 |
В операторе 1 объявляется переменная типа "указатель на указатель на int" и выделяется память под массив указателей на строки массива (количество строк
– nrow). В операторе 2 организуется цикл для выделения памяти под каждую строку массива. В операторе 3 каждому элементу массива указателей на строку присваивается адрес начала участка памяти, выделенного под строку двумерного массива. Каждая строка состоит из ncol элементов типа int. Освобождение памяти из под массива с любым количеством измерений выполняется с помощью операции delete [] a.
Упражнение 1. |
Упражнение 2.. |
|
//Массивы динамической памяти (задание одномерного массива |
//Массивы динамической памяти (задание двумерного массива |
|
неопределенной размерности) |
неопределенной размерности) |
|
#include "stdafx.h" |
#include "stdafx.h" |
|
#include "iostream" |
#include "iomanip" //Манипуляция выходными данными |
|
using namespace std; |
#include "iostream" |
|
int _tmain(int argc, _TCHAR* argv[]) |
using namespace std; |
|
|
|
|
{setlocale(LC_CTYPE, ""); |
int _tmain(int argc, _TCHAR* argv[]) |
|
int n; |
{setlocale(LC_CTYPE, ""); |
|
cout<<"Введите размерность массива: "; |
int nrow, ncol; |
|
cin>>n; |
cout<<"Введите количество строк и столбцов :"; |
|
int *array =new int[n]; //Динамическое выделение памяти |
cin>>nrow>>ncol; |
//Ввод размерности массива |
cout<<"Введите элементы массива (через пробел): "; |
int i,j; |
|
for (int i=0; i<n; i++) cin>>array[i]; |
int**a=new int *[nrow]; |
// Выделение памяти под массив |
cout<<"Вывод элементов массива занесенных в память: "; |
for (i=0; i<nrow; i++) a[i] = new int [ncol]; |
|
for (int i=0; i<n; i++) cout<<array[i]<<" "; |
cout<< "Введите элементы массива (через пробел): "<<endl; |
|
cout<<endl; |
for(i=0; i<nrow; i++) |
|
delete [ ] array; //Освобождение памяти |
for(j=0; j<ncol; j++) cin>>a[i][j]; |
|
return 0; |
cout<<"Вывод элементов массива занесенных в память: "<<endl; |
|
} |
for(i=0; i<nrow; i++) { |
|
|
for(j=0; j<ncol; j++) cout<<setw(4)<<a[i][j]<<" "; |
|
|
cout<<endl;} |
|
|
//setw(int n) – задает ширину поля вывода, что удобно для печати матриц |
|
|
delete [] a; |
|
|
return 0; } |
|