Создание программы циклической структуры. Работа с массивами

Автор работы: Пользователь скрыл имя, 07 Февраля 2013 в 06:04, курсовая работа

Описание

С развитием вычислительной техники образовались два основных направления ее использования. Это выполнение численных расчетов и использование средств вычислительной техники в автоматических или автоматизированных системах. Информационная система представляет собой программно-аппаратный комплекс, выполняющий функции поддержки надежного хранения информации в памяти компьютера, выполнении определенных преобразований информации, предоставления пользователям удобного интуитивно понятного интерфейса.

Работа состоит из  1 файл

массивы.doc

— 284.00 Кб (Скачать документ)

Глубина вложенности  структурированных типов вообще, а следовательно, и массивов - произвольная, поэтому количество элементов в списке индексных типов (размерность массива) не ограничено, однако суммарная длина внутреннего представления любого массива, не может быть больше 65520 байт. В памяти ПК элементы массива следуют друг за другом так, что при переходе от младших адресов к старшим наиболее быстро меняется самый правый индекс массива. При описании массива, как показано ниже:

var

а : array[1. .2,1. .2] of Byte;

begin

a[1,1]:=1;

a[2,1]:=2;

a[l, 2]:=3;

a[2,2]:=4;

end.

В памяти последовательно друг за другом будут расположены байты со значениями 1,3,2,4 . Это будет важно при использовании стандартной процедуры копирования памяти MOVE.

      1. Динамические массивы

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

Объявляется массив следующим  образом:

Var

DynamicArray: array of type;

где DynamicArray – название динамического массива, type – тип элементов массива.

Включение возможности работать с динамическим массивом происходит использование команды компиляции {R-}. Эта команда отключает контроль границ массива и позволяет программе обращаться к не существующим, при компиляции элементам массива.

Пример программы:

Type

NewType=word;

Type

TArray=Array[1..1] of NewType;

TArrayPtr=^TArray;

Var

DynamicArray: TArrayPtr;

SizeOfArray, Size, i: word;

Begin

Write('Размер массива: ');

ReadLn(SizeOfArray);

Size:=SizeOfArray*SizeOf(NewType);

GetMem(DynamicArray,Size);

For i:=1 to SizeOfArray do DynamicArray^[i]:=i;

For i:=1 to SizeOfArray do Write(DynamicArray^[i]:4); 

FreeMem(DynamicArray,Size);

End.

При работе с динамическими  массивами необходимо выделять память под массив. Выделение памяти производится процедурой GetMem. Входные параметры, передаваемые процедуре, название массива и размер выделяемой памяти в байтах. Расчет необходимой памяти простой: перемножение количества элементов массива на размер одного элемента в байтах. В данном примере Размер рассчитан как произведение полученного от пользователя размера массива на размер используемого типа SizeOfArray*SizeOf(NewType). После завершения работы с массивом необходимо освободить выделенную память. Это можно сделать путем вызова процедуры FreeMem. Передаваемые в процедуру параметры те же: название массива и размер освобождаемой памяти. Пренебрежение освобождением выделяемой памяти может привести к ошибкам на этапе выполнения программы. На этапе компиляции ошибок не будет, но при завершении работы программы не освобождённая память будет оставаться занятой.

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

На практике для работы с набором данных переменного  размера гораздо удобнее использовать предоставляемую средой разработки компоненту TList.

Переменные, описанные, как динамические массивы являются указателями, и операции с ними производятся как с указателями. Например, при присвоении одного массива другому элементы одного массива не копируются во второй, а копируется адрес массива. Соответственно, при  сравнении двух массивов в логических выражениях типа «равно — не равно» производится сравнением адресов, а не значений массивов. Пример присвоения одного массива другому:

program UsingDynamicArrays2;

var

  А, В: array of integer;

                             {Описание двух переменных —

                             динамических массивов целочисленных

                             элементов}

begin

  SetLength( A, 5);       { Установка размера массива А

                         (5 элементов ) }

  А[0] := 14;            {Присвоение значения 14 нулевому

                         элементу массива А}

  В := А;                {Присвоение массива А массиву  В, теперь

                         переменные А и В указывают  на один и

                         тот же массив}

  В[0] := 2;             {Присвоение нулевому элементу  массива В

                         значения 2, теперь нулевой элемент

                         массива А также имеет значение 2}

  FreeMem( A, 5);       { Освобождение памяти занятой  массивом}

end.

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

      1. Способы изменения элемента с указанным индексом

Для изменения элемента массива с указанным индексом достаточно просто присвоить новое  значение элементу. Например, для изменения  названия 10-го месяца на английское, достаточно выполнить команду:

Months[10] := ‘October’;

или

i :=10;

Months[i] := ‘October’;

Теперь при обращении  к элементу массива с индексом 10 будет получено новое значение – название месяца по-английски. От программиста требуется соблюдение мер для недопущения обращения в процессе работы программы к несуществующим индексам.

    1. Циклические структуры языка

2.3.1 Синтаксис циклических операторов

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

В языке Free Pascal предусмотрены  три оператора, реализующих циклический процесс: while, repeat…until и for.[3]

Если число повторений заранее известно, то подходящей конструкцией является оператор for. В противном случае следует использовать операторы while или repeat[1].

      1. Способы организации циклов, особенности различных операторов организации цикла

Оператор цикла с  предусловием while…do обозначает "пока" условие выполняется "делай" состоит из заголовка while c условием входа в цикл, проверяемого перед выполнением каждого цикла — это выражение логического типа: простое выражение, отношения или сложное логическое выражение и тела.

заголовка, тела и условия  окончания (until). Ключевые слова repeat, until обозначают соответственно "повторяй" и "пока" условие не выполниться.

While условие входа и нахождения в цикле do

Тело цикла 

Выражение, с помощью  которого осуществляется управление повторением оператора, должно иметь булевый тип. Вычисление его производится до того, как внутренний оператор будет выполнен. Внутренний оператор выполняется повторно до тех пор, пока выражение принимает значение True. Если выражение с самого начала принимает значение False, то оператор, содержащийся внутри оператора цикла с предусловием, не выполняется[1].

Пример организации цикла с предусловием:

var

i: integer;

y:integer;

begin

i := 1;

while i<=10 do

         begin

           y := i*i;

   i := i +1;

end;

end;

Оператор повтора repeat состоит из заголовка, тела и условия  окончания (until). Ключевые слова repeat, until обозначают соответственно "повторяй" и "пока" условие не выполниться.

Repeat

Тело цикла 

until Условие выхода  из цикла; 

Условие выхода из цикла  — это выражение логического  типа: простое выражение, отношения или сложное логическое выражение. Результат выражения должен быть результат булевского типа. Операторы, заключенные между ключевыми словами repeat и until, выполняются последовательно до тех пор, пока результат выражения не примет значение True. Последовательность операторов выполнится, по крайней мере, один раз, поскольку вычисление выражения производится после каждого выполнения последовательности операторов[1].

Пример организации  цикла с пост условием:

var

i: integer;

y: integer;

begin

i := 1;

repeat

i := i +1;

y := i*i;

until i=10;

end;

Операторы цикла с условием обладают значительной гибкостью, но не слишком удобны для организации «строгих» циклов, которые должны быть выполнены заданное число раз. Оператор цикла for…to…do или for…downto…do используется именно в таких случаях и обозначает "для счётчика начиная с" "по" "делай" и соответственно "для счётчика начиная с" "уменьшая до" "делай". При возвращении к началу цикла for..to..do автоматически увеличивает, а for..downto..do уменьшает счетчик на единицу соответствующую размерности счетчика. Его, как правило, используют для обхода интервала индексов массива. В качестве управляющей переменной должен использоваться идентификатор переменной (без какого либо квалификатора), который обозначает переменную, объявленную локальной в блоке, в котором содержится оператор for. Управляющая переменная должна иметь перечислимый тип. Начальное и конечное значения должны иметь тип, совместимый по присваиванию с перечислимым типом[1].

Ниже приведены два  примера оператора:

for i:= in to ik do оператор; //пример с увеличивающимся счётчиком

for i:= ik downto in do оператор; //пример с уменьшающимся счётчиком

где оператор – любой оператор языка, i, in и ik — переменная целочисленного или перечислимого типов. Переменную i называют параметром цикла. Переменные in и ik — диапазон изменения параметра цикла: in — начальное значение, а ik — конечное значение параметра цикла. Шаг изменения цикла for всегда постоянен и равен интервалу между двумя ближайшими значениями типа параметра цикла (при целочисленном значении параметра цикла шаг равен 1).

В случае если тело цикла  состоит более чем из одного оператора, необходимо использовать составной оператор:

for i:= in to ik do

begin

оператор_1;

оператор_2;

...........

оператор_n;

end;

Алгоритм работы цикла for…do:

1. Параметру цикла i присваивается начальное значение in.

2. Если значение параметра  цикла превосходит конечное значение (i>ik), то цикл завершает свою работу. В противном случае выполняется пункт 3.

3. Выполняется оператор.

4. Значение параметра  цикла i изменяется на соответствующий шаг и осуществляется переход к п.2 и т. д.

Этот алгоритм представляет собой цикл с предусловием.

Пример использования  оператора for:

Var

i: integer;

Y: integer;

Begin

For i:=1 to 10 do

Begin

y := i*i;

End;

End;

В этом примере высчитывается последовательно квадраты всех чисел от 1 до 10.

      1. Операторы передачи управления

Операторы передачи управления принудительно изменяют порядок  выполнения команд. В языке Free Pascal таких  операторов пять:

goto, break, continue, exit и halt.

Оператор goto метка, где метка обычный идентификатор, применяют для безусловного перехода, он передает управление оператору с меткой:

метка: оператор;

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

Операторы break и continue используют только внутри циклов. Так, оператор break осуществляет немедленный выход из циклов repeat, while, for и управление передается оператору, находящемуся непосредственно за циклом. Оператор continue начинает новую итерацию цикла, даже если предыдущая не была завершена. Оператор exit осуществляет выход из подпрограммы. Оператор halt прекращает выполнение программы.

 

      1. Применение циклических операторов для работы с массивом

Выведем последовательно  название месяцев по порядку при помощи операторов цикла for…to…do, while и repeat…until:

var

Months: array [1..12] of string = ('январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь');

i: integer;

begin

//вывод месяцев с  помощью оператора цикла for

for i:=1 to 12 do

begin

showmessage( Months[i]);

end;

//вывод месяцев с  помощью оператора цикла while

          i :=1;

while i<=12 do

begin

showmessage( Months[i]);

i := i +1;

end;

//вывод месяцев с  помощью оператора цикла repeat..until

          i :=1;

repeat

showmessage( Months[i]);

i := i +1;

until i>12 ;

end;

 

2.4 Разработка программы, работающей с массивами и использующей операторы организации циклов

Программа реализована на высокоуровневом языке программирования Free Pascal в среде разработке Lazarus.

Программа реализует следующие возможности:

- запрос у пользователя  количество элементов

- заполнение массива  заданного размера случайными  числами

- сортировка массива  по возрастанию или убыванию (по  выбору пользователя).

Текст программы приведен в Приложении.

Используемые в программе компоненты:

    BitBtn, Button – компоненты кнопок. Использование компоненты BitBtn вызвано только эстетическими соображениями и экземпляры класса BitBtn вполне могут быть заменены без потери функциональности на экземпляр класса TButton.

Label – компонента текстовых надписей. Экземпляры этого класса используются только для статичного вывода вспомогательной информации.

Memo – компонента вывода текста. Экземпляр этого класса используется для вывода массива построчно.

Panel – компонента организации графических элементов в рабочем окне программы. Экземпляр этого класса используется для визуальной компоновки элементов окна.

SpinEdit – компонента изменения численного значения. Экземпляр этого класса используется для указания размера массива. Компонента была использована потому, что методы класса позволяют ограничивать минимальное и максимальное значение изменяемой величины.

Рассмотрим процедуру  заполнения массива случайными значениями. Процедура вызывается при обработке события «Нажатие кнопки btnEnterSizeofArray».

procedure TfrmMain.btnEnterSizeofArrayClick(Sender: TObject);

var

   i: integer; // Номер элемента массива

begin

     // Генерируем  новый массив

     // очищаем  массив

     CurrArray[0] := 0;

     // Очищаем  Поле отображения массива

     mmShowArray.Lines.Clear;

     intSize := edSizeOfArray.Value ;

     for i:=1 to intSize do

     begin

          CurrArray[i] := trunc ( Random(intSize) );

          mmShowArray.Lines.Add( IntToStr(CurrArray[i]) );

     end;

end;

Рассмотрим ход выполнения программы при выполнении этой процедуры:

CurrArray[0] := 0; - обнуляем размер массива.

mmShowArray.Lines.Clear; - Вызываем  метод Clear класса Memo. Этот метод очищает все элемента свойства  Lines. Происходит очищение строк выведенных на экран ранее.

Информация о работе Создание программы циклической структуры. Работа с массивами