Главная страница
Навигация по странице:

  • GetMem(p,n)

  • Length(a)

  • High(a)

  • Array of тип

  • High, Low, Length

  • программирование на паскале2. Учебное пособие по курсу Высокоуровневые методы информатики и программирования для студентов Гуманитарноприкладного института


    Скачать 0.89 Mb.
    НазваниеУчебное пособие по курсу Высокоуровневые методы информатики и программирования для студентов Гуманитарноприкладного института
    Анкорпрограммирование на паскале2.doc
    Дата25.05.2018
    Размер0.89 Mb.
    Формат файлаdoc
    Имя файлапрограммирование на паскале2.doc
    ТипУчебное пособие
    #19648
    страница9 из 10
    1   2   3   4   5   6   7   8   9   10

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


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

    Классический подход к работе с массивами переменной длины, который в настоящее время используется, например, в алгоритмическом языке Си, состоит в следующем. После определения числа n элементов массива (например, посредством ввода) с помощью процедуры, аналогичной GetMem(p,n), выделяется область памяти под массив. Указатель p при этом ссылается на первый элемент массива. Адреса остальных элементов легко вычисляются по их индексам. Например, адрес i-го элемента в одномерном массиве равен p+(i-1)*s, где s – количество байтов, занимаемых одним элементом. В Объектном Паскале такой подход невозможен, так как ограничено использование арифметических операций над указателями. Это ограничение позволяет увеличить надежность программы за счет уменьшения вероятности несанкционированного доступа к памяти из-за неправильного определения адресов.

    Как альтернатива описанного выше подхода, в Объектном Паскале для работы с массивами переменной длины определен специальный тип – динамические массивы. Описание динамического массива:

    Var имя_массива: Array of Array of…Array of тип_элемента;

    Ключевые слова Array of записываются в описании столько раз, сколько индексов у массива. По существу объявленное имя_массива является указателем на массив. Начальное значение индексов динамического массива равно нулю.

    Выделение памяти под массив осуществляется с помощью процедуры SetLength (см. также §3.1.2). Вызов этой процедуры имеет вид:

    SetLength(имя_массива, размер1, размер2,…,размерM).

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

    Пример 1. В приведенном ниже фрагменте программы выделяется память под вещественный одномерный массив a размером n и под целочисленную матрицу b из n строк и m столбцов. Значения n и m предварительно задаются вводом.

    Var a:Array of Real; b:Array of Array of integer; n,m:integer;

    Begin

    Readln(n,m);

    SetLength(a,n); SetLength(b,n,m);…

    Для работы с массивами (необязательно динамическими) также используются функции:

    Length(a) – возвращает размер массива a по первому индексу;

    Low(a) – возвращает наименьший номер компонента массива a (для динамических массивов ноль);

    High(a) – возвращает наибольший номер компонента массива a;

    SizeOf(a) –возвращает число байтов памяти, занимаемых массивом a.

    Для освобождения памяти, отведенной под динамический массив, достаточно присвоить его имени значение nil.

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

    program Primer2;

    Var a:Array of Array of real; n,m,i,j:integer; {n,m – размеры матрицы}

    {i,j – счетчики строк и столбцов}

    Begin

    writeln(’Input count of rows’); readln(n);

    writeln(’Input count of columns’); readln(m);

    SetLength(a,n); {отводится память под указатели на строки}

    writeln(’Input array ’, n, ’*’,m);

    for i:=0 to High(a) do {High(a)=n-1)}

    begin

    Setlength(a[i],m); { отводится память под элементы строки}

    for j:=0 to High(a[i]) do {High(a[i]=m-1}

    read(a[i,j]);

    end; readln; {закончен ввод динамического массива}

    // обработка матрицы – заглушка

    writeln(’ output of dynamic array’);

    for i:=0 to High(a) do

    begin

    for j:=0 to High(a[i]) do

    write (a[i,j]:7:2); writeln;

    a[i]:=nil; {освобождение памяти из-под строки}

    end;

    a:=nil;{ освобождение памяти из-под указателей на строки }

    readln

    End.
      1. Формальные параметры-массивы без указания границ


    В части II приводились примеры подпрограмм с параметрами-массивами. Тип массивов объявлялся до описания подпрограмм в разделе типов, причем размеры выбирались по максимальной длине фактических массивов, используемых в данной задаче. Такой подход, несомненно, имеет два недостатка: во-первых, теряется универсальность подпрограммы, а, во-вторых, память по фактические массивы объявляется с избытком.

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

    Открытые массивы могут быть только одномерными, но их компоненты могут иметь сложный тип. Нумеруются элементы открытых массивов начиная с нуля. При работе с открытыми массивами, наряду с функциями High, Low, Length, может быть полезна функция
    Slice(массив, количество_элементов), возвращающая начальную часть массива.

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

    program Project1;

    Var A:Array[1..5] of real; B:Array[1..8] of real;

    Procedure masin( c:char; Var A:array of real);

    Var i:integer;

    begin

    writeln('input vector',c,' size of ',Length(A));

    for i:=Low(A) to High(a)do

    read(A[i]); readln;

    end{masin};

    Function max( Var A:array of real):real;

    Var i:integer;mx:real;

    begin

    mx:=a[Low(A)];

    for i:=Low(A)+1 to High(A) do

    if mx
    mx:=A[i];

    max:=mx

    end{max};

    begin

    masin('A',A); masin('B',B);

    writeln('maxa=',max(A),' maxb=',max(b)); readln

    end.

    Пример 2. В отличие от примера 1, приведенная программа позволяет обрабатывать не все элементы массивов (в соответствии с описанием), а только совокупность первых элементов массивов, число которых задается вводом. Эта возможность обеспечивается применением функции Slice.

    program Project2;

    Var A:Array[1..10] of real; B:Array[1..10] of real; nA,nB:integer;

    Procedure masin( c:char; Var A:array of real);

    Var i:integer;

    begin

    writeln('input vector',c,' size of ',Length(A));

    for i:=Low(A) to High(a)do

    read(A[i]);

    readln;

    end{masin};

    Function max( Var A:array of real):real;

    Var i:integer;mx:real;

    begin

    mx:=a[0];

    for i:=Low(A)+1 to High(A) do

    if mx
    mx:=A[i];

    max:=mx

    end{max};

    begin

    writeln('Input number of components of array A');

    readln(nA);

    masin('A',Slice(A,nA));

    writeln('Input number of components of array B');

    readln(nB);

    masin('B',Slice(B,nB));

    writeln('maxa=',max(Slice(A,nA)),' maxb=',max(Slice(B,nB)));

    readln

    end.

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

    program Project3;

    Type str=array of real;{тип строки матрицы – динамический массив}

    Var nA,mA,nB,mb:integer; A,B:array of str;

    Function Sum(n,m:integer; Var a:array of str):real;

    Var s:real; i,j:integer;

    Begin

    s:=0;

    for i:=0 to n-1 do

    for j:=0 to m-1 do

    s:=s+a[i][j];

    sum:=s

    End {Sum};

    Procedure InMatr(n,m:integer; c:char;Var A:array of str);

    Var i,j:integer;

    Begin

    writeln('input matrix ', c, ' size of ', n, '*', m);

    for i:=0 to n-1 do

    begin

    SetLength(a[i],m);

    for j:=0 to m-1 do

    read(a[i][j]);

    end; readln;

    End;

    begin

    writeln ('Input sizes of matrix A'); readln (nA,mA);

    SetLength(A,nA);

    InMatr(nA,mA,'A',A);

    writeln ('Input sizes of matrix B'); readln (nB,mB);

    SetLength(B,nB);

    InMatr(nB,mB,'B',B);

    writeln('sumA=',Sum(nA,mA,A):6:1,' sumB=',Sum(nB,mB,B):6:1); readln;

    end.
    1   2   3   4   5   6   7   8   9   10


    написать администратору сайта