Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Абстрактные типы данных, модули и классы(v1.2).doc
Скачиваний:
4
Добавлен:
14.08.2019
Размер:
418.3 Кб
Скачать

Инкапсулированные (неимпортируемые) инструменты модуля:

  • Инструменты, локализованные в блоках описания функций, импортировать невозможно, они невидимы даже в своём модуле за пределами области их видимости.

  • Только максимальноглобальные инструменты модуля (программного файла) можно импортировать, т.е. только те, которые объявлены вне описаний функций.

  • Для инкапсуляции инструмента (защиты от импорта) в начале его объявления ставится ключевое слово static. Модификатор класса памяти static допустим только для переменных, констант и функций, т.е. защитить определение типа от импорта невозможно. Попытка импорта инкапсулированного инструмента пресекается на этапе редактирования межмодульных связей после трансляции всех модулей многомодульной программы.

Модификатор класса памяти static применим и к локальным переменным. Как показано в таблице 2 на предыдущей странице, воздействие модификатора static на глобальные и локальные переменные заметно различается. Для глобальных переменных – он сужает область видимости (но не изменяет период жизни), а для локальных – расширяет период жизни (но не изменяет область видимости). Локальные static-переменные - это что-то новое в дилемме локальные - глобальные. При выходе из своего блока, области видимости этой переменной, она не уничтожается, как это происходит с обычной локальной переменной, и сохраняет своё значение. А потому при повторном входе в свой блок восстанавливается её последнее значение от предыдущего входа в этот блок.

Интерфейсные (экпортируемые) инструменты модуля:

  • Импортировать можно любой максимальноглобальный инструмент модуля, не защищённый модификатором static в его объявлении.

Импорт инструментов модуля:

Импортирование оформляется в импортирующем модуле повторным объявлением инструмента, а точнее ссылкой на основное собственно объявление этого инструмента в экспортирующем модуле:

  • Импорт функции: включить (в импортирующий модуль) прототип этой функции. Можно в начало прототипа поставить ключевое слово extern, но этот модификатор класса памяти для функций устанавливается по умолчанию.

  • Импорт переменной: включить объявление этой переменной, но с модификатором extern (в начале объявления) и без инициализации.

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

  • Импорт типа: оформляется полным повторным объявлением.

Повторные объявления – опасная штука, могут появиться расхождения в этих объявлениях и сопутствующие им недоразумения... Чтобы оградить программиста от технических проблем, сопутствующих повторным объявлениям, в С/С++ используется понятие «заголовочный h-файл» и директива препроцессорных средств #include:

  • В заголовочный h-файл включается весь импорт модуля.

  • #include ИмяФайлаОбрамлённое

Эта директива имеет следующий смысл: заменить текст директивы текстом файла, имя которого указано в директиве. Если параметр директивы задан в виде <ИмяФайла>, то файл ищется в предопределенном каталоге среды программирования, а если в виде строковой константы ”ИмяФайла” – то в текущем каталоге проекта. Директивы препроцессорных средств обрабатываются препроцессором до трансляции модуля.

  • Вариант 1. С/С++. Статическая реализация стека.

На следующей странице приведена С/С++-программа статической реализации стека вместе с выше рассмотренной Pascal-программой для визуального сравнения.

UNIT UVal; INTERFACE TYPE TVal= CHAR;

PROCEDURE WriteElement(xPrm:TVal);

CONST CMaxL=1000 {статическая реализация - размер стека

изначально ограничен};

IMPLEMENTATION

PROCEDURE WriteElement(xPrm:TVal); BEGIN WRITE(xPrm) END;

END.

UNIT UStack;

INTERFACE USES UVal;

FUNCTION Empty:BOOLEAN {Проверить на пустоту};

PROCEDURE Push(xPrm:UVal.TVal){Добавить, положить в стек};

PROCEDURE Pop {Удалить, вытолкнуть из стека};

FUNCTION Top:UVal.TVal {Посмотреть вершину};

PROCEDURE WriteAll {Вывести все элементы стека};

VAR ErrStack:INTEGER {Код ошибки};

IMPLEMENTATION

TYPE TStack= RECORD Elem: ARRAY[1..CMaxL] OF UVal.TVal;

Top: 0..CMaxL END;

VAR Stack: TStack;

FUNCTION Empty:BOOLEAN; BEGIN Empty:=(Stack.Top=0) END;

PROCEDURE Push(xPrm:UVal.TVal);

BEGIN IF Stack.Top=CMaxL THEN {переполнение} ErrStack:=-1

ELSE BEGIN Stack.Top:=Stack.Top+1;

Stack.Elem[Stack.Top]:=xPrm END END;

PROCEDURE Pop;

BEGIN IF Stack.Top=0 THEN {стек пустой} ErrStack:=-2

ELSE Stack.Top:=Stack.Top-1 END;

FUNCTION Top:UVal.TVal;

BEGIN IF Stack.Top=0 THEN {стек пустой} ErrStack:=-2

ELSE Top:=Stack.Elem[Stack.Top] END;

PROCEDURE WriteAll; VAR i:INTEGER; BEGIN

FOR i:=1 TO Stack.Top DO WriteElement(Stack.Elem[i]) END;

INITIALIZATION {Создать пустой стек} Stack.Top:=0; ErrStack:=0

END.

program Project1; uses UVal, UStack; LABEL 1;

VAR Vh,Vih: FILE OF CHAR; x,y: CHAR; begin RESET(Vh); REWRITE(Vih);

WHILE NOT EOF(Vh) DO BEGIN READ(Vh,x);

IF ErrStack<0 THEN BEGIN WRITE(’ErrStack=’,ErrStack); goto 1 END;

IF x='(' THEN ELSE

IF (x='+')OR(x='-')OR(x='*')OR(x='/') THEN UStack.Push(x) ELSE

IF x=')' THEN BEGIN y:=UStack.Top; WRITE(Vih,y); UStack.Pop END

ELSE {'a'..'z'} WRITE(Vih,x);

END; 1:end. PROGRAM\PRG3A\Project1.dpr

Файл UVal.h:

typedef char TVal; void WriteElement(TVal xPrm);

//extern const int CMaxL; // надо бы так, но... см. UStack.cpp

const int CMaxL=1000; // размер стека изначально ограничен

Файл UVal.cpp: #include "UVal.h"

//const int CMaxL=1000; // надо бы так, но... см. UVal.h

void WriteElement(TVal xPrm){cout<<xPrm;}

Файл UStack.h:

void MakeNull(); //Создать пустой стек

bool Empty(); //Проверить на пустоту

void Push(TVal xPrm); //Добавить, положить в стек

void Pop(); //Удалить, вытолкнуть из стека

TVal Top(); //Посмотреть вершину

void WriteAll(); //Вывести все элементы стека

extern int ErrStack; //Код ошибки

Файл UStack.cpp: #include "UVal.h"

int ErrStack; //Код ошибки

//!!! не разрешает массив с размером - внешняя константа:

typedef struct{TVal Elem[CMaxL]; int Top;} TStack;

static TStack Stack;

void MakeNull(){Stack.Top=-1; ErrStack=0;};

bool Empty(){return (Stack.Top==-1);}

void Push(TVal xPrm)

{if(Stack.Top==(CMaxL-1)) ErrStack=-1;//переполнение

else{ Stack.Top=Stack.Top+1; Stack.Elem[Stack.Top]=xPrm; }};

void Pop(){ if(Stack.Top==-1) ErrStack=-2; // стек пустой

else Stack.Top=Stack.Top-1; };

TVal Top(){ if(Stack.Top==-1) ErrStack=-2; // стек пустой

else return Stack.Elem[Stack.Top]; }

void WriteAll(){int i;

for(i=0;i<=Stack.Top;i++) WriteElement(Stack.Elem[i]);}

Файл PRG3A.cpp: #include "UVal.h"

#include "UStack.h"

main(){ ifstream Vh; ofstream Vih; char x,y;

Vh.open("VhPrg3.TXT"); Vih.open("VihPrg3.TXT"); MakeNull();

while(Vh.peek()!=EOF){ Vh.get(x);

if(ErrStack<0){ cout<<"ErrStack="<<ErrStack; goto m1;}

if(x=='(');else

if((x=='+')||(x=='-')||(x=='*')||(x=='/')) Push(x); else

if(x==')'){ Vih<<Top(); Pop();}

else /*'a'..'z'*/ Vih<<x;

} m1:;} PROGRAM\C(C++)\PRG3A\PRG3A.dsw

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]