Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СТА (лекции+лабы) / СТА Лекция 1.docx
Скачиваний:
54
Добавлен:
16.03.2016
Размер:
336.41 Кб
Скачать

Int main ()

{

// Приглашение пользователя ко вводу

std::cout << "Input integers, stop with Ctrl+Z: ";

// Инициализация динамически растущего массива:

// - выделение 10 начальных ячеек

// - счетчик занятых ячеек приравнивается к 0

// - счетчик выделенных ячеек равен 10

const int INITIAL_ALLOCATION_SIZE = 10;

int * pData = new int[ INITIAL_ALLOCATION_SIZE ];

int nUsed = 0, nAllocated = INITIAL_ALLOCATION_SIZE;

// Пытаемся вводить числа с консоли одно за другим

while (true )

{

// Попытка ввода числа

int temp;

std::cin >> temp;

if ( std::cin )

{

// Проверяем достаточно ли места в массиве

if ( nUsed == nAllocated )

{

// Места недостаточно, необходимо расширить массив.

// Выделяем новый блок вдвое больше существующего

int nAllocatedNew = nAllocated * 2;

int * pNewData = new int[ nAllocatedNew ];

// Переносим данные и существующего блока в новый

memcpy( pNewData, pData, sizeof( int ) * nAllocated );

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

delete[] pData;

pData = pNewData;

// Обновляем количество выделенных ячеек на новое

nAllocated = nAllocatedNew;

}

// Записываем данные в массив, точно зная, что место есть

pData[nUsed++ ] = temp;

}

else

// Конец ввода

break;

}

// Количество введенных данных сохранено в переменной nUsed

// Выводим данные в обратном порядке

for (int i =nUsed- 1; i >= 0; i-- )

std::cout << pData[ i ] << ' ';

std::cout << std::endl;

// Освобождаем последний выделенный блок данных

delete[]pData;

}

Новая версия программы заметно сложнее, тем не менее, она справляется с любым реальным объемом входных данных, при этом корректно завершается и рационально расходует память. Для 51 числа процедура расширения выполнится 3 раза (10->20, 20->40, 40->80), в последнем блоке останется 29 свободных ячеек.

Рефакторинг решения

Предложенное выше решение задачи удовлетворило выдвинутым требованиям, однако количество и сложность внесенного программного когда, необходимого для поддержания структуры динамически растущего массива, заметно превысили размеры самой задачи. Фактически, разглядеть контуры решения основной изначальной задачи в таком громоздком коде стало затруднительно. Желательно отделять код обеспечения структур данных от кода основной задачи для улучшения восприятия при чтении. Важен ли данный фактор? Несомненно, ведь профессиональный программист в реальных проектах читает существующий код в 5-10 раз чаще, чем пишет новый. а значит чтение должно даваться легко.

Еще одной побудительной причиной отделения может стать необходимость повторного использования структуры данных в других задачах. Ведь необходимость хранения последовательности чисел заранее неизвестной длины - типичная потребность для многих программ. Применим методы РЕФАКТОРИНГА - процесса изменения исходного кода программы с целью улучшения его внутренней структуры без влияния на внешне наблюдаемую функциональность.

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

Соседние файлы в папке СТА (лекции+лабы)