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

Проблема фиксированного размера массивов

Предположим имеется тривиальная задача вывести поступающую от пользователя последовательность целых чисел в обратном порядке. Такая задача предполагает хранение всей входной последовательности в памяти программы. Достаточно знать длину последовательности, выделить массив подходящего размера, считать данные в массив и затем вывести их на экран в обратном порядке. Предположим пользователь будет вводить последовательность из 10 чисел с содержимым “1 2 3 4 5 6 7 8 9 10”, ожидаемый результат в таком случае - “10 9 8 7 6 5 4 3 2 1”. Ниже приведен первый простейший вариант реализации и вывод программы:

#include <iostream>

Int main ()

{

   // Длина входной последовательности

   const int SEQUENCE_LENGTH = 10;

   

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

   std::cout << "Input " << SEQUENCE_LENGTH << " integers: ";

   

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

   int data[ SEQUENCE_LENGTH ];

   // Ввод данных с консоли в массив

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

       std::cin >> data[ i ];

   // Вывод данных на консоль в обратном порядке

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

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

   std::cout << std::endl;

}

Серьезная проблема этой программы состоит в том, что размер последовательности фиксирован и равен 10. На практике довольно редко встречаются задачи, в которых количество данных фиксировано и строго прописывается в явном виде в коде программы. Обычно объем входных данных варьируется в зависимости от потребностей пользователя.

Предположим, пользователь будет вводить длину последовательности в начале выполнения программы. Это все еще не похоже на реальную ситуацию, но все же заметно повышает гибкость рассматриваемой программы. Теперь программа сможет обрабатывать последовательности с длиной отличной от 10. Получив от пользователя желаемую длину последовательности, выделяем массив для хранения данных в динамической памяти, ведь заранее предсказать размер этих данных мы не можем. В дальнейшем решение отличается от предыдущего лишь явной инструкцией по освобождению выделенной динамической памяти:

#include <iostream>

Int main ()

{

   // Вводим длину последовательности

   std::cout << "Input length of the sequence: ";

   int sequenceLength;

   std::cin >> sequenceLength;

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

   std::cout << "Input " << sequenceLength << " integers: ";

   

   // Выделяем массив нужной длины в динамической памяти

   int * pData = new int[ sequenceLength ];

   // Ввод данных с консоли в массив

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

       std::cin >> pData[ i ];

   // Вывод данных на консоль в обратном порядке

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

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

   std::cout << std::endl;

   // Освобождение динамической памяти

   delete[] pData;

}

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

Простейшее грубое решение - выделить некоторый достаточно большой объем памяти  (допустим, для 50 чисел) и надеяться, что пользователь столько данных не введет. Решение могло бы выглядеть следующим образом:

#include <iostream>