Освобождение памяти из-под массива с любым количеством измерений выполняется с помощью операции delete [].
В нашем случае матрица – квадратная (то есть число строк совпадает с числом столбцов), поэтому используется одна переменная и для обозначения строк и для столбцов.
Оператор:
fill(Ar,S);- обращение к функции заполнения матрицы. Функции передаются: указатель на начало массива и размерность матрицы.
После возврата управления из функции fill() уже готовая матрица выводится на экран. При выводе матрица рассматривается как линейный массив из S2 элементов. Счетчик i меняется от 0 до S2-1. Но обращение к элементам матрицы в этом цикле ведется через указатель Cr. В начальных установках этот указатель устанавливается на начало массива, а после каждой итерации увеличивается на 1, т.е. сдвигается на следующий элемент массива. Счетчик i используется для определения момента выхода из цикла, а также для перехода на новую строку экрана после вывода каждых S элементов - для этого проверяется условие: i%S==S-1.
|
|
Последним действием в функции main() является освобождение с помощью функции delete [] выделенной ранее памяти под массив данных и под массив указателей.
Функция fill() получает параметры - указатель на начало массива и размерность матрицы. Тело функции начинается с объявления ее локальных переменных, переменная k получает начальное значение при объявлении.
Далее в функции организуются вложенные циклы для перебора строк и столбцов. Но номера строки и столбца используются не для обращения к элементам матрицы, а только для проверки, попадает ли элемент в нулевую или ненулевую область (в точном соответствии условиям, приведенным в п.5.2). Обращение к элементам матрицы ведется через указатель C, который указывает на текущий элемент матрицы. Этот указатель устанавливается на начало массива в начальных установках внешнего цикла и увеличивается на 1 в конце каждой итерации внутреннего цикла.
Полный текст программы приведен ниже.
/***************************************************/
/* Лабораторная работа 11 */
/* Функции */
/* Пример выполнения. Вариант ╧30. */
/* Вариант реализации 2 */
/***************************************************/
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
void fill(int **, int);
/*** главная функция ***/
int main()
{
int **Ar; /* указатель на массив указателей */
//int a;
int i, j; /* строка и столбец */
const int S=9; /* размерность матрицы */
/* выделение памяти для массива указателей */
Ar=new int* [S];
/* выделение памяти для каждой строки
и заполнение массива указателей */
for (i=0; i<S; i++)
Ar[i]=new int[S];
/* обращение к функции заполнения матрицы */
fill(Ar,S);
|
|
/* вывод матрицы */
for (i=0; i<S; i++) {
for (j=0; j<S; cout<<setw(5)<<Ar[i][j++]);
cout<<endl;
}
/* освобождение памяти строк */
for (i=0; i<S; delete Ar[i++]);
/* освобождение памяти массива указателей */
delete [] Ar;
getch();
return 0;
}
/*** функция заполнения матрицы ***/
/* параметры: A - указатель на массив указателей
s - размерность матрицы */
void fill(int **A, int s) {
int l, r; /* строка и столбец */
short k=1; /* текущий член ЛП */
for (l=0; l<s; l++) /* перебор строк */
for (r=0; r<s; r++) /* перебор столбцов */
/* условие нулевого значения */
if ((r>=max(l,s-l-1))||(r<=min(l,s-l-1)))
A[l][r]=0;
else A[l][r]=k++;
/* конец перебору строк */
/* конец перебору столбцов */
}
}5.5. Отличия для варианта реализации 1
В тексте программы для варианта реализации 1 мы для упрощения исключили все проверки корректности и использовали для динамического массива устаревшие функции malloc и free. Описание реализации мы ограничиваем только отличиями от варианта 1.
Указатель Ar в функции main() тут - указатель на массив указателей, следовательно, его тип - int**. Выделение памяти ведется в несколько приемов: сначала выделяется память для массива из S указателей, а потом в цикле - S раз выделяется память для массива из S целых чисел, адреса выделенных массивов записываются в элементы массива указателей. При выводе матрицы используются i и j - номера строки и столбца и обращение к элементам матрицы ведется как к элементам 2-мерного массива.
Первый параметр функции fill() - указатель на указатель на int. Это дает возможность использовать номера строки и столбца - l и r также и для обращения к элементам матрицы.
/***************************************************//* Лабораторная работа ╧11 *//* Функции *//* Пример выполнения. Вариант ╧30. *//* Вариант реализации 2 *//***************************************************/#include <stdio.h>#include <stdlib.h>#include <alloc.h>void fill(int far **, int); /*** главная функция ***/main() { int far **Ar; /* указатель на массив указателей */ int i, j; /* строка и столбец */ int S; /* размерность матрицы */ /* ввод размерности */ printf("Enter S>"); scanf("%d",&S); printf("S=%d\n",S); /* выделение памяти для массива указателей */ Ar=(int far **)malloc(sizeof(int *)*S); /* выделение памяти для каждой строки и заполнение массива указателей */ for (i=0; i<S; i++) Ar[i]=(int far *)malloc(sizeof(int)*S); /* обращение к функции заполнения матрицы */ fill(Ar,S); /* вывод матрицы */ for (i=0; i<S; i++) { for (j=0; j<S; printf("%3d",Ar[i][j++])); putchar('\n'); } /* освобождение памяти строк */ for (i=0; i<S; free(Ar[i++])); /* освобождение памяти массива указателей */ free(Ar); return 0;}/*** функция заполнения матрицы ***//* параметры: A - указатель на массив указателей s - размерность матрицы */void fill(int far **A, int s) { short l, r; /* строка и столбец */ short k=1; /* текущий член ЛП */ for (l=0; l<s; l++) /* перебор строк */ for (r=0; r<s; r++) /* перебор столбцов */ /* условие нулевого значения */ if ((r>=max(l,s-l-1))||(r<=min(l,s-l-1))) A[l][r]=0; else A[l][r]=k++; /* конец перебору строк */ /* конец перебору столбцов */}