Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СТА (лекции+лабы) / Структуры и алгоритмы обработки данных.docx
Скачиваний:
99
Добавлен:
16.03.2016
Размер:
1.9 Mб
Скачать

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 раз чаще, чем пишет новый. а значит чтение должно даваться легко.

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

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