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

Инициализация многомерных массивов может проводиться по аналогии с одномерными массивами. Например:

int A[2][3][2]={ 1, 2, 3, 4, 5};

Инициализируются первые 5 элементов по их расположению в оперативной памяти, т.е. элементы с индексами: 000, 001, 010, 011, 020

Но удобнее использовать вложенные фигурные скобки, при этом самая левая размерность может не указываться, а определяться по умолчанию:

int B[][5]={{ 1, 2, 3} , { 6, 7} , { 1, 2, 3, 4, 5 }};

В примере создается массив размерности 3 × 5 (аналог матрицы 3 × 5, при этом в первой строке инициализируются 3 элемента, во второй – 2 элемента, в третьей – все 5 элементов).

Динамические многомерные массивы

По аналогии с одномерными массивами многомерные массивы могут создаваться динамически. Рассмотрим пример создания двухмерного массива n × m (матрица n × m), при этом значения n и m заранее неизвестны – вводятся с клавиатуры. В примере создается матрица n × m, заполняется случайными числами, выводится на печать, в конце программы память освобождается.

#include <stdio.h>

#include <stdlib.h>

void main()

{

int **p; // Указатель на указатель может быть использован для выделения памяти под

// 2-х мерный массив динамически

int n, m; // Заранее неизвестные размерности массива

int i, j; // Индексные переменные

printf_s("n="); scanf_s("%d", &n); // Ввод с клавиатуры числа строк матрицы

printf_s("m="); scanf_s("%d", &m); // Ввод с клавиатуры числа столбцов матрицы

p = malloc(n*sizeof(int *)); // Выделяем память под массив указателей только в Си

// p=(int **)malloc(n*sizeof(int *)); В Си++ требуется преобразование типа

// Выделяем память для каждого указателя в массиве указателей

for (i = 0; i<n; i++) p[i] = malloc(m*sizeof(int)); // Только в Си

// for(i=0; i<n; i++) p[i]=(int *)malloc(m*sizeof(int)); В Си++ требуется преобразование типа

// Заполняем массив (матрицу) случайными числами и печатаем его

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

{

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

{

p[i][j] = rand() % 100; // Получаем псевдослучайное целое число

printf_s("%d ", p[i][j]);

}

printf_s("\n"); // После печать строки матрицы переход на новую строчку

}

// Освобождаем память, порядок освобождения обратен порядку выделения

for (i = 0; i<n; i++) free(p[i]); // Освобождаем память для строк матрицы

free(p);// освобождаем память для массива указателей

system("pause");

}

Задачи и порядок выполнения работы

Лабораторная работа состоит из двух частей: одномерные массивы и многомерные массивы. Студент выполняет обе части.

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

Во второй части работы используются двухмерные массивы (матрицы). Матрицы также формируются с помощью генератора случайных чисел, размерности матриц вводятся с клавиатуры. Исходные данные и результаты работы вывести на печать. Для исходных данных небольшой размерность провести ручной расчет для контроля результатов. При изменении матриц (сортировка строки, запись строки в обратном порядке, транспонирование матрицы и др.) новые массивы (матрицы) не создавать.

Примеры выполнения работы

Пример 1

Условие задачи:

Задан одномерный массив вещественных чисел. Написать программу, которая "переворачивает" массив, т. е. меняет местами его первый и последний элементы, второй и предпоследний и т. д.

Для решения задачи в среде Microsoft Visual Studio 2013 было создано стандартное консольное приложение (проект типа Win32 Console Application) с установленным свойством «пустой проект» (Empty project). В проект добавлен файл с расширением .cpp, исходный код которого приведен ниже.

Листинг программы с комментариями:

#include <stdio.h>

#include <stdlib.h>

void main()

{

double *pMas; // Указатель на массив

int n; // Заранее неизвестная размерность массива

// Вводим размерность массива с клавиатуры

printf_s("n=");

scanf_s("%d", &n);

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

pMas = (double *)malloc(n*sizeof(double));

// Заполняем массив случайными числами в интервале [0, 100)

// и печатаем число

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

{

pMas[i] = rand() % 100;

printf("%f ", pMas[i]);

}

// Переворачиваем массив

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

{

// Меняем 2 элемента местами, используя буферную переменную

double buf = pMas[i];

pMas[i] = pMas[n - 1 - i];

pMas[n - 1 - i] = buf;

}

// Печатаем полученный массив

printf("\n");

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

printf("%f ", pMas[i]);

// Освобождаем память

free(pMas);

// Останавливаем программу, ждем нажатия любой клавиши

system("pause");// Останавливаем программу, ждем нажатия любой клавиши

}

Пример 2

Условие задачи:

«Улитка». Матрицу M(m, n) заполнить натуральными числами от 1 до m x n по спирали, начинающейся в левом верхнем углу и закрученной по часовой стрелке.

Для решения задачи в среде Microsoft Visual Studio 2013 было создано стандартное консольное приложение (проект типа Win32 Console Application) с установленным свойством «пустой проект» (Empty project). В проект добавлен файл с расширением .cpp, исходный код которого приведен ниже.

Листинг программы с комментариями:

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char* argv[])

{

int **pMatr;

int n, m;

printf_s("n="); scanf_s("%d", &n);

printf_s("m="); scanf_s("%d", &m);

pMatr = (int **)malloc(n*sizeof(int *));

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

pMatr[i] = (int *)malloc(m*sizeof(int));

int i = 0, j = 0, // Текущие координаты улитки

minx = 0, maxx = m - 1, miny = 0, maxy = n - 1; // Границы поля движения

int step = 1; // Шаг перехода (может быть 1 или -1)

bool flag = true; // Направление движения

// улитки true - горизонтальное false - вертикальное

for (int k = 0; k<n*m; k++)

{

pMatr[i][j] = k + 1;

if (flag)

{

if (step>0) if (j<maxx) j++;

else {

miny++;

flag = false;

i++;

}

else

if (j>minx) j--;

else {

maxy--;

flag = false;

i--;

}

}

else // Движение было вертикальное

if (step>0) if (i<maxy) i++;

else {

maxx--;

flag = true;

step = -1;

j--;

}

else

if (i>miny) i--;

else {

minx++;

flag = true;

step = 1;

j++;

}

}

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

{

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

printf_s("%4d", pMatr[i][j]);

printf_s ("\n");

}

// Освобождаем память

for (int i = 0; i<n; i++) free(pMatr[i]);

free(pMatr);

system("pause");// Останавливаем программу, ждем нажатия любой клавиши

return 0;

}

Наши рекомендации