Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции(ЯВУ)-Паскаль.doc
Скачиваний:
63
Добавлен:
31.03.2015
Размер:
1.08 Mб
Скачать
    1. Операции над указателями

Переменная типа «указатель» может находиться в трех состояниях:

  1. Указатель содержит адрес какой-либо переменной, память под которую уже выделена.

  2. Указатель содержит специальный, пустой адрес nil.

  3. Указатель находится в неопределенном состоянии.

В неопределенном состоянии указатель бывает в начале работы программы до размещения переменной в памяти ЭВМ и присвоения указателю конкретного адреса или значения nil.

Над указателями можно выполнять следующие операции:

  1. Объявление.

Type PInt = ^integer;

Var a,b: Pint;

Указатели a,bнаходятся в неопределенном состоянии.

  1. Выделение памяти под переменную.

Type PInt = ^integer;

Var a,b: Pint;

………………………….

New(a); New(b);

Указатели a,bпринимают значения адресов распределенной под неименованные переменные памяти. Обращение к этим переменным осуществляется с помощью операции косвенной адресации;a^,b^ – значения динамически размещенных переменных.

  1. Присвоение указателю значения адреса нединамической переменной.

Var

P: ^char;

P1: ^char;

ch: char;

…………….

P:=@ch; { @ - операция определения адреса }

…………….

New(P1); …..P:=P1; {присвоение указателю значения другого указателя }

Присвоение указателю значения возможно двумя способами:

  • с помощью операции @ определения адреса другой переменной;

  • с помощью присвоения указателю значения другого указателя.

  • Занесение информации по адресу, хранимому в переменной типа «указатель» a^:=^b; илиa^:=2;

  • Освобождение памяти.

    Dispose(a);

    Указатель aпереходит в неопределенное состояние. Различие между состояниемnilи неопределенным состоянием состоит в следующем. Если два указателяp1 иp2 имеют значениеnil, то результат операции сравненияp1=p2 естьtrue. Если указателиp1 иp2 находятся в неопределенном состоянии, то их невозможно сравнивать.

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

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

      1. Программа создания и обработки линейного списка

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

    PN

    Информ. Поле1

    Адрес 2-го элемента

    Информ. Поле2

    Адрес 3-го элемента

    ………..

    Информ. Поле n-1

    Адрес n-го элемента

    Информ. Поле n

    nil

    Рис. 10.1.

    На рис. 10.1 используются следующие обозначения:

    PN– адрес первого элемента списка, который запоминается для работы со списком при его создании;

    nil- признак последнего элемента списка.

    Над линейными списками выполняются следующие операции:

    • создание пустого списка;

    • последовательный просмотр списка и поиск заданного элемента;

    • добавление нового элемента в упорядоченный список;

    • добавление элемента в конец списка;

    • добавление элемента в начало списка;

    • удаление заданного элемента из списка.

    В программе на языке Паскаль элемент линейного списка объявляется с помощью типа «запись» следующего вида:

    Туре TElem=recodrd

    Inf:integer; {информационное поле}

    Next:TPtr{ поле связи (адрес следующего элемента списка) }

    End;

    TPtr– тип «указатель», который объявляется следующим образом:

    Type TPtr=^ TElem;

    Указательный тип используется для определения переменных, значением которых являются адреса размещенных в памяти переменных, тип которых совпадает с типом указателя. Для размещения в памяти элементов списка используется стандартная процедура динамического распределения памяти; в языке Паскаль эта процедура имеет имя New. Для удаления элемента из списка служит стандартная процедура освобождения памятиDispose. Адресное поле последнего элемента списка содержит значениеnil, специальный, пустой адрес, который является признаком конца списка.

    Пример программы создания и обработки линейного списка.

    program Project2;

    {$APPTYPE CONSOLE}

    uses

    Windows;

    type TPtr=^TElem;

    TElem=record

    Inf:integer;

    Next:TPtr;

    end;

    Var Beg: TPtr; Value: integer; Rejim: byte;

    Procedure Init_list(Var P: TPtr);

    Begin P:=nil; end;

    Procedure Add_list(Var P: TPtr);

    Var PT,TPR,Prev:TPtr; Prizn: byte;

    begin

    write('Input Value: '); read(Value);

    if P=nil then begin New(TPR); P:=TPR;

    TPR^.Inf:=Value; TPR^.Next:=nil;

    write('First element of list is created - ',Value);

    end

    else begin PT:=P; PREV:=nil; Prizn:=0;

    while PT<>nil do

    begin if Value<PT^.Inf then begin

    if PREV=nil then begin

    New(TPR); P:=TPR; TPR^.Inf:=Value;

    TPR^.Next:=PT;

    write('Element ',Value,' added before first element'); end

    else begin

    New(TPR); PREV^.Next:=TPR; TPR^.Inf:=Value;

    TPR^.Next:=PT;

    Write('Element ',Value, ' is added between two other elements ');

    end;

    Prizn:=1; break;

    end;

    PREV:=PT; PT:=PT^.Next;

    end;

    if Prizn=0 then begin

    New(TPR); TPR^.Inf:=Value;

    TPR^.Next:=nil; PREV^.Next:=TPR;

    write('Element ',Value, ' is added after last element');

    end; end;

    end;

    Procedure Del_Elem(Var P: TPtr);

    Var

    PT,TPR,Prev:TPtr; Prizn: byte;

    begin

    if P=nil then write('list is empty!!!')

    else begin write('Input value: '); read(Value);

    PT:=P; PREV:=nil; Prizn:=0;

    while PT<>nil do begin

    writeln(PT^.Inf);

    if Value=PT^.Inf then begin

    if PREV<>nil then begin

    PREV^.Next:=PT^.Next; Prizn:=1;

    write('Element is deleted '); break;

    end

    else begin P:=PT^.Next; Prizn:=1;

    write('Element is deleted '); break;

    end;

    Dispose(PT);

    end;

    PREV:=PT; PT:=PT^.Next;

    end;

    if Prizn=0 then write('Element is not founded ' );

    end;

    end;

    Procedure Display_list(P: TPtr);

    Var

    PT:TPtr; i: byte;

    begin

    i:=0; PT:=P;

    if P=nil then begin write('list is empty!!!'); exit; end;

    Writeln; write(' List =[');

    while PT<>nil do

    begin i:=i+1;

    write(PT^.Inf,' '); PT:=PT^.Next;

    end;

    write(']'); write(' Number of elements = ',i);

    end;

    begin

    while True do

    begin

    writeln;

    write('0 -- Exit; '); write('1 -- Create; '); write('2 -- Display; ');

    write('3 -- Add; '); writeln('4 -- Delete; '); writeln('Input option (0 -- 4)');

    readln(Rejim);

    case(Rejim) of

    0: begin readln; exit; end;

    1: Init_list(Beg);

    2: Display_list(Beg);

    3: Add_list(Beg);

    4: Del_Elem(Beg)

    else write('Error!!! ')

    end; end; end.

    Результаты работы программы.

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    1

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    3

    Input Value: 3

    First element of list is created - 3

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    3

    Input Value: 8

    Element 8 is added after last

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    3

    Input Value: 6

    Element 6 is added between two other elements

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    2

    List =[3 6 8 ] Number of elements = 3

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    4

    Input value: 6

    3

    6

    Element is deleted

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    2

    List =[3 8 ] Number of elements = 2

    0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

    Input option (0 -- 4)

    Очередь – это частный случай линейного списка; новый элемент в очередь добавляется только после последнего элемента, а удаляется только первый элемент очереди (см. рис.10.2).

    BegQ

    Информ. Поле1

    Адрес 2-го элемента

    Информ. Поле2

    Адрес 3-го элемента

    ………..

    Информ. Полеn-1

    Адрес n-го элемента

    EndQ

    Информ. Поле n

    nil

    Рис. 10.2.

    При создании очереди запоминаются адреса первого и последнего элемента BegQиEndQ, соответственно. Над очередями допустимы следующие операции:

    • создание пустой очереди;

    • включение элемента в очередь;

    • исключение элемента из очереди;

    • отображение на экране всех элементов очереди.

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

    1. создание пустого стека;

    2. размещение элемента в стеке;

    3. удаление элемента;

    4. последовательный просмотр и обработка элементов.