Практическое занятие 7. Двумерные массивы. Организация работы с динамической памятью

 

 

Двумерные массивы

В языке С++ предусмотрены многомерные массивы. Простейшим из них является двумерный. Объявление двумер­ного статического массива b, состоящего из 10 строк и 15 столбцов, выглядит следующим образом:

 

int b[10][15];

 

В памяти такой массив располагается в последовательных ячейках памяти построчно. Многомерные массивы размещаются так, что при переходе к следующему элементу быстрее всего меняется последний индекс. Для доступа к элементу многомер­ного массива указываются все его индексы, например, b[i][j] или *(b[i]+j), или *(*(b+i)+j). b[i] является адресом начала i-той строки массива.

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

 

int mas[][]={{1,1},{0,2},{1,0}};

int mas[3][2]={1,1,0,2,1,0};

 

Можно инициализировать элементы массива одинаковыми значениями, используя функцию memset (объявлена в файлах <memory.h>, <string.h>, <cstring>, <iostream> библиотеки языка):

 

void *memset(const void *p, int ch, size_t n);

 

Она заполняет начинающийся с адреса p блок памяти зна­чением, находящимся в младшем байте аргумента ch. Размер за­полняемого блока (в байтах) передаётся аргументом n. Этот спо­соб удобен при необходимости обнулить все элементы массива:

 

int m1[2][5];

memset(m1, 0, 2*5*sizeof(int));

 

Можно копировать весь массив целиком, используя функцию memcpy (<memory.h>, <string.h>, <iostream>):

 

void *memcpy(void *dest, const void *src,

size_t count);

 

Она копирует начинающийся с адреса src блок памяти в область памяти, начинающуюся с адреса dest. Размер копируемого блока (в байтах) передаётся аргументом count. Скопировать все элементы массива mas1 в mas2 можно так:

 

int mas1[6] = {1,1,0,2,1,0};

int mas2[6];

memcpy(mas2, mas1, 6*sizeof(int));

 

Рассмотрим пример работы с двумерными массивами.

 

Задача 1. Для вещественной матрицы размером 3´4 определить среднее арифметическое её элементов и количество отрицательных элементов в каждой строке.

 

// Листинг 7.1

#include <fstream>

#include <iostream>

using namespace std;

int main() {

setlocale(LC_ALL, "Russian");

// Число строк и столбцов матрицы

const int n = 3, m = 4;

double a[n][m]; // Определение матрицы

int i, j, num;

 

// Заполнение матрицы (ввод с клавиатуры)

cout << "Введите матрицу с клавиатуры" << endl;

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

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

cin >> a[i][j];

 

// Вывод матрицы на экран

cout << "Матрица:" << endl;

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

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

cout << a[i][j] << "\t"; // Конец for j

cout << endl;

} // Конец for i

 

// Вычисление среднего арифметического и кол-ва

// отрицательных элементов в каждой строке

double average = 0;

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

num = 0;

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

average += a[i][j];

if(a[i][j] < 0)

++num;

}

cout << "В строке " << i <<

" отрицательных элементов " << num << endl;

}

average /= n*m;

cout <<"Среднее арифметическое "<<average<<endl;

return 0;

}

 

Результат выполнения программы:

 

Введите матрицу с клавиатуры

-1 2 3 -4

5 6 7 8

9 -10 11 12

Матрица:

-1 2 3 -4

5 6 7 8

9 -10 11 12

В строке 0 отрицательных элементов 2

В строке 1 отрицательных элементов 0

В строке 2 отрицательных элементов 1

Среднее арифметическое 4

 

Динамические массивы

 

Динамические массивы создают с помощью операции new языка С++ или с помощью функций динамического распределения памяти библиотеки С.

В случае, когда память для массива выделяется с помощью оператора new, он имеет следующий вид:

 

указатель = new тип_массива[размер];

 

Здесь размер задаёт количество элементов размещаемого массива. Например:

 

int n = 100;

double * k = new double[n];

 

Создаётся переменная k – указатель на double, в динами­ческой памяти (heap-области) отводится непрерывный участок, достаточный для размещения 100 элементов вещественного типа, и адрес начала этого участка заносится в указатель k.

Если память выделить не удалось, по стандарту должно порождаться исключение std::bad_alloc.

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

Преимущество динамических массивов состоит в том, что размерность может быть задана переменной, поскольку выделение памяти осуществляется на этапе выполнения програм­мы. Доступ к элементам динамического массива осуществляется точно так же, как к статическим. Например, к 10-му элементу массива k можно обратиться как k[10] или *(k + 10).

Память, зарезервированная для динамического массива с помощью оператора new [], должна освобождаться оператором delete [], который имеет следующий вид:

 

delete [] указатель;

 

Например: delete [] k;

 

Задача 2. Ввести с клавиатуры набор вещественных чисел, количество которых заранее не фиксировано, и найти среди них максимальное число.

 

// Листинг 7.2

#include <iostream>

using namespace std;

 

int main() {

double max;

int i, n;

cout << "Input n" << endl;

cin >> n; // n - число элементов в массиве

 

// Выделение динамической памяти

double * a = new double[n];

for (i = 0; i < n; ++i) // Цикл ввода чисел

cin >> a[i];

 

// Определение максимального элемента

max = a[0];

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

if (a[i] > max) max = a[i];

cout << "max = " << max << endl;

delete [] a; // Освобождение памяти

return 0;

}

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: