Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lectures_2.doc
Скачиваний:
28
Добавлен:
15.03.2015
Размер:
511.49 Кб
Скачать

Абстракция сущностей и процедурный язык программирования

Рассмотрим возможность реализации абстракции сущности (пользовательский тип) средствами процедурного языка программирования (например, языка С). Основная сложность состоит в отсутствии в языке Cспециальной синтаксической конструкции, предназначенной для этой цели. Будем исходить из общих соображений. Тип данных задается двумя множествами:

  • Множеством значений, которые могут принимать данные рассматриваемого типа.

  • Множеством операций, которые можно применять к таким данным.

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

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

Приведем пример. Разработаем пользовательский тип данных стек. Выберем одну из простейших реализаций стека. Стек будет реализован с помощью статического массива. Размер памяти массива будет определяться символической константой, задаваемой с помощью директивы define(#includeMAXSIZE20).

В структуре будем инкапсулировать две величины:

  • Целочисленное значение вершины стека (inttop)

  • Объявление массива. Для определенности предположим, что стек будет работать с данными типа double(doublear[MAXSIZE]).

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

  • init() – инициализация стека (необходимо задать начальное значение переменнойtop).

  • push() – затолкнуть в стек.

  • pop() – вытолкнуть из стека.

  • top() – возвращает значение, находящееся на вершине стека.

  • isEmpty() – проверка состояния «Стек пуст»

  • isFull() – проверка состояния «Стек полон»

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

// файл Stack.h #define MAXSIZE 20 struct Stack { int top; double ar[MAXSIZE]; }; void init(Stack *pstk); void push(const Stack *pstk, double item); double pop(Stack *pstk); double top(const Stack *pstk); bool isEmpty(const Stack *pstk); bool isFull(const Stack *pstk); // Файл Stack.c #include “Stack.h” void init(Stack *pstk) { pstk-> top = -1; } void push(const Stack *pstk, double item) { pstk->ar[++pstk->top] = item; } double pop(Stack *pstk) { return pstk->top--; } double top(const Stack *pstk) { return pstk->ar[pstk->top]; } bool isEmpty(const Stack *pstk) { if(pstk->top == -1) return true; return false; } bool isFull(const Stack *pstk) { if(pstk->top >= SIZEMAX - 1) return true; return false; } // Файл main.c Клиентский код #include <stdio.h> #include <stdlib.h> #include “Stack.h” Stack stk1; init(&stk1); int n; printf(“n=”); scanf(“%d”, &n); for(int i = 0; i < n; i++) { if(!isFull(&stk1) push(&stk1, i * i); else { printf(“Переполнение стека\n”); exit(1); } } int m; printf(“m=”); scanf(“%d”, &m); for(int i = 0; i < n; i++) { if(!isEmpty(&stk1())) printf(“%0.4g\n”, pop(&stk1)); else { printf(“Cтек пуст\n”); exit(1); } } return 0; }

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

  • имеется возможность создавать переменные заданного типа.

  • к этим переменным можно применять операции, присущие стеку; реализован интерфейс стека.

Однако имеется и ряд существенных недостатков:

  • реализация типа оказалась незащищенной. Клиентский код имеет доступ к полям переменной. Отсутствует инкапсуляция абстракции.

  • функции, реализующие интерфейс, находятся в глобальном пространстве имен.

Соседние файлы в предмете Программирование