Формирование динамического массива осуществляется в два этапа: на первом – выделяют под массив динамическую память, на втором – инициализируют (заполняют данными) выделенную память. После обработки массива и получения результатов использованную память необходимо освобождать. Выделение и освобождение динамической памяти под массив производится по указателю при помощи операций new и delete соответственно. Контроль за правильностью выполнения операции выделения динамической памяти осуществляется с помощью макроса assert, определенного в файле <assert.h>. Например,
int n, *iptr; // n – размер массива
------------ инициализация n -------------
iptr = new int[n];
assert(iptr!=0);
// инициализация элементов массива случайными числами
Операция new выделяет непрерывный участок динамической памяти под массив длиной n, для целых чисел, и возвращает адрес этого участка, т.е. адрес элемента массива с индексом 0 – iptr[0]. Если память не выделена, то значение указателя iptr окажется равным нулю, а значение выражения iptr!=0 – ложным (нулевым). Тогда макрос assert прерывает выполнение программы. При завершении работы выводится сообщение об ошибке вида: Assertion failed: expression, file <имя файла>, line <номер строки>. После того, как отладка программы будет закончена и макросы assert будут больше не нужны, в начале программы достаточно добавить строку #define NDEBUG вместо того, чтобы удалять в программе каждый макрос assert вручную. Операция delete объявляет участок памяти под массивом свободным. После применения операции delete указатель рекомендуется обнулять, с целью защиты программного продукта.
ДВУМЕРНЫЕ МАССИВЫ (МАТРИЦЫ)
Выделение и освобождение динамической памяти для размещения двумерного массива (матрицы) выполняется, например, следующим образом.
int n, m, **iptr; // n – число строк, m – число столбцов матрицы
------------ инициализация n, m -------------
// выделение памяти под массив указателей на строки
// освобождение памяти под массивом указателей на столбцы
delete[]iptr;
iptr=0;
Задания
1.В одномерном массиве нулевые элементы удалить, положительные элементы расставить по убыванию, отрицательные - по возрастанию. Получить зависимость затрат машинного времени от размера массива.
2.В матрице удалить строки с последними отрицательными элементами, а затем добавить строку из сумм элементов по столбцам.
Проектирование приложения.
Выбор, размещение и задание свойств компонентов.
Коды обработчиков событий и функций
1.Запустите C++Builder 6.
2.Создайте новый проект командой Файл/Новый/Приложение.
3.Сохраните файлы модуля и проекта командой Файл/Сохранить все под именами LR_1 и PR_LR_1 в каталоге ТЕХН_ПРОГР. Для этого удобно использовать соответствующую быструю кнопку (Сохранить все). В последующих сеансах работы сохраненный проект можно открыть командой Файл/Открыть проект (или Повторно открыть). Теперь перейдем к проектированию приложения - переносам на форму необходимых компонентов и заданию их свойствам значений, а в обработчиках событий – размещению кодов соответствующих алгоритмов. (Рекомендуется нажимать кнопку Сохранить все по окончании работы с каждым компонентом.) В результате проектирования получим форму, представленную на рис.1.1,2,3.
4.Выделите форму, щелкнув на ней левой кнопкой мыши, и в свойство Caption (надпись) впишите ДИНАМИЧЕСКИЕ МАССИВЫ.
5.Вначале перенесите на форму многостраничную панель – компонент PageControl1 (страница Win32). Для размещения остальных компонентов приложения достаточно использовать две страницы компонента – по заданиям 1 и 2 соответственно.
6.Щелкните на компоненте PageControl1 правой кнопкой мыши и во всплывшем меню дважды используйте команду Новая страница. В свойство Caption первой страницы впишите массив, второй – матрица. Установите свойства компонента PageControl1: MultiLine – false, Style – tsTabs, TabPosition – tpTop.
7.Перенесите на первую страницу (массив) компонент PageControl2 и, как и в PageControl1, создайте две страницы, с надписями тестирование и использование и графики соответственно.
8.На страницу тестирование и использование (рис.1.1) перенесите семь меток Label (страница Стандарт), в свойство Caption (надпись) которых соответственно впишите размер массива, начальный, конечный, шаг, диапазон чисел, макс, мин; пять компонентов ввода целых чисел – CSpinEdit (страница Примеры) для задания параметров формируемых массивов.
Рис.1.1 – форма по окончании проектирования (вид 1)
Рис.1.2 – форма по окончании проектирования (вид 2)
Рис.1.3 – форма по окончании проектирования (вид 3)
10.Для разрешения или запрещения вывода на экран исходных и результирующих массивов, а также графиков полученных зависимостей, в правую верхнюю часть страницы перенесите два компонента-индикатора CheckBox (страница Стандарт), в свойство Caption которых впишите соответственно вывод в таблицу и графики, а свойство Alignment обоих компонентов установите в taRightJustify.
11.Ниже индикаторов CheckBox поместите панель Panel1( страница Стандарт) для вывода в нее сообщений: Макс значение не м.б. меньше мин значения!, В массиве только нули!, Кол-во сравнений = <число> Кол-во обменов = <число> . Очистите свойство Caption у панели.
12.Для вывода массивов на экран при тестировании перенесите на страницу компонент StringGrid1 (страница Дополнительно). Установите следующие значения свойств компонента StringGrid1: ColCount – 11, DefaultColWidth -24, FixedCols – 1, FixedRows – 0, Font – черный, обычный, размер 8, RowCount – 8.
14.Для отображения процесса обработки массива ниже компонента StringGrid1 поместите компонент ProgressBar1 (страница Win32).
15.Еще ниже поместите компонент StatusBar1 (страница Win32), который представляет собой ряд панелей, отображающих полосу состояния. Поскольку в нашем случае достаточно одной панели (для одного сообщения), то установите свойство SimplePanel = true. Свойство SimpleText представляет собой текст, который задается во время проектирования или программно (в нашем случае во время проектирования). Итак, в свойство SimpleText впишем кратко задание 1: Нули - удалить, "+" - элементы расставить по убыванию, "-" - по возрастанию.
16.Затраты машинного времени на обработку массива оценивают косвенно – по количествам сравнений и обменов. Для вывода на экран зависимостей количеств сравнений и обменов от размера массива, на страницу графики (рис.1.2) компонента PageControl2 перенесите компоненты Chart1 и Chart2 (страница Additional).
17.Задайте свойства компонента Chart1. Для этого щелкните правой кнопкой мыши на компоненте Chart1 и в появившемся меню выберите Edit Chart…. На экране появится окно Редактора Диаграмм (Editing Chart1) с открытой страницей Chart,которая имеет несколько закладок. В данный момент открыта закладка Series. Щелкните на кнопке Add… - добавить серию. В появившемся окне выберите тип графика – Line и выключите индикатор 3D. На закладке Panel, нажав кнопку Panel Color…, выберите белый цвет. Перейдите на закладку Titles. В окне редактирования, которое в данный момент соответствует Title – заголовку графика, сотрите TChart и напишите (шрифт Font… - черный, жирный, размер 8) количество сравнений. Цвет фона Back Color.. установите белый.В выпадающем списке от окна редактирования Title перейдите в окно редактирования Foot и напишите тем же шрифтом размер массива. Цвет фона Back Color.. также установите белый. Нажмите кнопку Close и выйдите из режима редактирования компонента Chart1. Свойства компонента Chart2 задаются так же.
18.Перейдем к обработчикам событий – щелчков на кнопках ПУСК1 и СБРОС1. В первом обработчике размещен алгоритм формирования и обработки массива по заданию 1, а также вывод сообщений и результатов в виде таблицы и графиков, а во втором – подготовка компонентов к выводу новых сообщений и новых результатов. Перед, после и в обработчике щелчка на кнопке ПУСК1 напишите (курсив):
20.Перенесите на вторую страницу (матрица) компонента PageControl1 (рис.1.3) восемь меток Label (страница Стандарт), в свойство Caption (надпись) которых впишите значения размеры, число строк, число столбцов, диапазон чисел, макс, мин, исходная матрица, матрица-результат; четыре компонента ввода целых чисел – CSpinEdit6…9 (страница Примеры) для задания параметров формируемых матриц.
21.У компонента, расположенного правее метки число строк (CSpinEdit6), занесите в свойство MaxValue – 100, MinValue – 1, Value – 10; правее метки число столбцов(CSpinEdit7) - MaxValue – 100, MinValue – 1, Value – 10; правее метки макс(CSpinEdit8) - MaxValue – 99, MinValue – -99, Value – 9, правее метки мин (CSpinEdit9) - MaxValue – 99, MinValue – -99, Value – -9.
22.Перенесите также две кнопки Button1,2 (страница Стандарт) с надписями ПУСК2, СБРОС2.
23.Сюда же поместите панель Panel2 (страница Стандарт) для вывода в панель сообщений: Макс не м.б. меньше мин!, В матрице удалены все строки!, В матрице нет удаленных строк!, В матрице удалено <кол-во> строк(и)!.Очистите свойство Caption у панели.
24.Кроме того, на этой странице разместите две таблицы - компоненты StringGrid2,3 (страница Дополнительно) - для вывода матриц – исходной и матрицы-результата. Задайте следующие значения свойств обоих компонентов StringGrid: ColCount – 10, DefaultColWidth - 32, FixedCols – 0, FixedRows – 0, Font – черный, обычный, размер 8, RowCount – 10.
25.И, наконец, в нижней части страницы поместите компонент StatusBar2 (страница Win32). Установите свойство SimplePanel = true. В свойство SimpleText впишите кратко задание 2: Строки с "-" на конце - удалить, а затем добавить строку из сумм по столбцам.
26.В обработчике щелчка на кнопке ПУСК2 находится алгоритм формирования и обработки динамической матрицы согласно заданию 2 с выводом результатов и сообщений, а в обработчике щелчка на кнопке СБРОС2 - зачистка выведенных результатов и сообщений (курсив):
1.Запустите приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск.
2.Подготовьте приложение к тестированию задания 1, щелкнув на закладке массив, а затем тестирование и использование (рис.1.1). Включите индикатор вывод в таблицу.
3.Пользуясь ПУСК1 и СБРОС1, убедитесь в работоспособности приложения с параметрами массива, заданными по умолчанию (рис.1.4).
4.Изменяя диапазон значений элементов массива, убедитесь в работоспособности приложения в случаях: а) максимальное значение меньше минимального, б) в массиве только нули, в) в массиве только положительные элементы, г) в массиве только отрицательные элементы, д) массив состоит из равных по величине элементов (положительных и отрицательных).
5.Перейдите к использованию приложения для построения графиков зависимостей затрат машинного времени от размера массива при разных диапазонах значений элементов массива. Включите индикатор графики. При заданных по умолчанию остальных параметрах задайте конечный размер массива – 1000 и нажмите ПУСК1. По окончании обработки массива получите на вкладе графики результат, представленный на рис.1.5.
Рис.1.4 – результаты тестирования по заданию 1
Рис.1.5 – зависимости затрат машинного времени от размера массива
6.Установите влияние диапазона значений элементов и размера массива на ход указанных зависимостей. В частности, установите параметры диапазона такими, чтобы количество обменов было нулевым при любом размере массива.
7.Подготовьте приложение к тестированию и выполнению задания 2, щелкнув на закладке матрица (рис.1.3).
8.Протестируйте приложение для заданных по умолчанию параметрах матрицы, щелкая на кнопках ПУСК2 и СБРОС2 (рис.1.6).
Рис.1.6 – результаты тестирования по заданию 2
9.Изменяя диапазон значений элементов матрицы, убедитесь в работоспособности приложения в случаях: а) максимальное значение меньше минимального, б) удалены все строки, в) нет удаленных строк. Установите влияние диапазона на среднее количество удаленных строк.
10.Проделайте то же самое, варьируя размерами матрицы.
11.Для завершения работы щелкните на кнопке формы “Закрыть” и выйдите из среды Builder.
Контрольные вопросы
1.Как еще можно использовать свойство Caption (надпись) формы? Приведите примеры фрагментов кода.
2.Какие свойства компонента PageControl используются в приложении? Как установить значения этих свойств?
3.Поясните назначения компонентов StringGrid в приложении. Значения каких свойств использованы по умолчанию, а у каких значения по умолчанию пришлось изменить?
4.Расскажите порядок установки значений свойств компонента Chart. Каким свойствам можно задать другие значения без ущерба для качества представления результатов?
5.Какую функцию выполняют в приложении компоненты CheckBox? Для ответа воспользуйтесь кодом.
6.Как задаются размеры массива и матрицы? Поясните по коду.
7.Используя код, объясните, как задается диапазон значений элементов массива.
8.Используя код, объясните, как задается диапазон значений элементов матрицы.
9.Используя код, объясните, как задаются значения элементов массива и матрицы.
10.Расскажите порядок установки значений свойств компонента CSpinEdit.
11.Можно ли компоненты Panel заменить на компоненты Label?
12.Поясните назначение компонентов StatusBar. Укажите и объясните фрагменты кода, относящиеся к этим компонентам. Как вывести сообщение в компоненты во время выполнения приложения?
13.Поясните назначение компонента ProgressBar. Укажите и объясните фрагменты кода, относящиеся к этому компоненту. Изобразите закон изменения переменной current по времени.
14.Используя код, объясните, как удаляются из массива нули. Представьте алгоритм.
15.Используя код, объясните, как сортируются в массиве положительные элементы. Представьте алгоритм.
16.Используя код, объясните, как сортируются в массиве отрицательные элементы. Представьте алгоритм.
17.Как выводятся на экран исходный массив и массив, полученный в результате сортировки? Для ответа используйте код.
18.Как строятся графики зависимостей? Для объяснения воспользуйтесь кодом. Объясните вид зависимостей.
19.Как выводятся на экран исходная матрица и матрица, полученная после обработки? Для ответа обратитесь к коду.
20.Используя код, объясните, как выделяется динамическая память под формируемые массив и матрицу и как она освобождается. Представьте алгоритмы.
21.Какие операции с динамической памятью выполняются во время обработки матрицы?
22.Представьте алгоритм удаления из матрицы строк с последними отрицательными элементами.
23.Представьте алгоритм добавления строки в матрицу согласно коду.
24.Что происходит при щелчке на кнопках ПУСК1 и ПУСК2?
25.Что происходит при щелчке на кнопках СБРОС1 и СБРОС2?
Задания
1.В матрице удалить строки, содержащие нули, а затем добавить строку, элементы которой равны произведениям элементов в соответствующих столбцах.
2.В матрице удалить столбцы с нулевыми элементами ниже главной диагонали, а затем добавить столбец, элементы которого равны суммам элементов в соответствующих строках.
3.В матрице удалить столбцы, в которых количество отрицательных элементов превышает заданное, а затем в качестве первого добавить столбец с максимальными элементами по строкам.
4.В матрице удалить строки с нулевыми элементами выше главной диагонали, а затем в качестве третьей добавить строку, элементы которой равны разностям соответствующих элементов первой и второй строк
5.В матрице удалить столбцы с положительными суммами элементов, а затем в качестве первого вставить столбец из минимальных элементов соответствующих строк.
6.В матрице удалить строку с минимальным произведением элементов, а затем в качестве второй добавить строку, элементы которой равны разностям элементов первой и последней строк.
7.В матрице удалить строки, последние элементы которых отрицательны, а затем в качестве первой добавить строку из элементов заданного массива.
8.В матрице удалить первую и последнюю строки, а затем добавить строку из максимальных элементов соответствующих столбцов.
9.В матрице удалить столбцы с отрицательной суммой элементов, а затем добавить столбец из минимальных элементов соответствующих строк.
10.В матрице удалить столбцы с максимальным и минимальным элементами матрицы, а затем на место первого добавить столбец из произведений элементов соответствующих строк.
11.В матрице удалить строки с элементами на главной диагонали, превышающими заданную величину, а затем в качестве первой вставить строку из максимальных элементов соответствующих столбцов.
12.В матрице удалить столбцы с положительными третьими элементами, а затем добавить столбец из элементов заданного массива.
13.Вычислить m-норму матрицы.
14.Вычислить l-норму матрицы.
15.Вычислить k-норму матрицы.
16.В матрице удалить строки с положительными последними элементами, а затем добавить строку из минимальных элементов по соответствующим столбцам.
17.Сформировать массивы из элементов в седловых точках матриц. Примечание: в седловой точке элемент является минимальным в строке и максимальным в столбце.
18.Приняв за характеристику столбца матрицы сумму модулей его отрицательных нечетных элементов, расположить столбцы матриц в соответствии с ростом характеристик.
19.Выполнить операции сглаживания матриц. Операция сглаживания дает матрицу того же размера, каждый элемент которой получается как среднее арифметическое соседей соответствующего элемента матрицы. Соседями элемента в матрице называют элементы с
20.Элемент матрицы называется локальным минимумом, если он строго меньше всех имеющихся у него соседей. Сформировать массив из количеств локальных минимумов обработанных матриц.
21.Осуществить циклический сдвиг элементов прямоугольных матриц на n элементов вправо или вниз (в зависимости от указанного режима); n может быть больше количества элементов в строке или столбце матрицы.
22.Осуществить циклический сдвиг элементов квадратных матриц вправо на k элементов таким образом: элементы первой строки сдвигаются в последний столбец сверху вниз, из него – в последнюю строку справа налево, из неё - в первый столбец снизу вверх, из него – в первую строку; для остальных элементов – аналогично.
23.Сортировать матрицы следующим образом: помещать элементы на диагонали, начиная с главной диагонали, в порядке убывания.
24.В матрице удалить строку с минимальным элементом матрицы, а затем добавить отсортированную по возрастанию предыдущую строку.
25.В матрицах проверять указанную строку на ортогональность остальным строкам.
26.В матрице удалить строку с максимальным по модулю элементом матрицы, а затем в качестве первой добавить строку, элементы которой равны суммам модулей элементов в соответствующих столбцах.
27.Проверять матрицы на попарную ортогональность строк; обработку каждой матрицы завершать выводом списка попарно ортогональных строк.
28.Характеристикой строки матрицы назовём сумму её отрицательных четных элементов. Расположить строки в соответствии с убыванием характеристик.
29.В матрице удалить столбец с максимальным элементом матрицы, а затем вставить заданный столбец перед столбцом с минимальным элементом полученной матрицы.
30.В матрицу добавить строку из элементов заданного массива, а затем удалить строки с положительной суммой элементов.