|
Программирование >> Составные структуры данных
в коде программы 3.2. Затем можно создать второй файл заголовков с другими описаниями typedef и randNum и использовать главную программу 3.2 безо всяких изменений с любым из файлов, переименовав требуемый файл в Number.h. Третий метод рекомендован и широко распространен в программировании на С, С++ и других языках. Он предусматривает разбиение программы на три файла: Интерфейс, где определяется структура данных и объявляются функции, используемые для управления этой структурой Реализация функций, объявленных в интерфейсе Клиентская программа, которая использует функции, объявленные в интерфейсе, для реализации более высокого уровня абстракции Подобная организация позволяет использовать программу 3.2 с целыми и значениями с плаваюшей точкой, либо расширить ее для обработки других типов данных путем простой компиляции совместно со специальным кодом для поддерживаемого типа данных. В последуюших абзацах рассматриваются изменения, необходимые для данного примера. Под термином интерфейс подразумевается описание типа данных. Это соглашение между клиентской программой и программой реализации. Клиент соглашается обращаться к данным только через функции, определенные в интерфейсе, а реализация соглашается предоставлять необходимые функции. Для программы 3.2 интерфейс должен включать следующие объявления: typedef int Number; Ntunber randNum О ; Первая строка указывает на тип обрабатываемых данных, а вторая - на операции, связанные с этим типом. Этот код можно поместить в файл с именем, например, Number.h, где на него будут независимо ссылаться клиенты и реализации. Реализация интерфейса Number.h заключена в функции randNum, которая может содержать следующий код: #include <stdlib.h> #include Number.h Number randNum () { return randO ; } Первая строка ссылается на предоставленный системой интерфейс, который описывает функцию rand(). Вторая строка ссылается на реализуемый интерфейс (она включена для проверки того, что реализуемая и объявленная функции имеют одинаковый тип). Две последних строки представляют собой код функции. Этот код можно сохранить в файле, например, int.c. Реальный код функции rand содержится в стандартной библиотеке времени выполнения С++. Клиентская программа, соответствующая примеру 3.2, будет начинаться с директив include для интерфейсов, где объявлены используемые функции: #include <iostream.h> #include <math.h> #include Number.h После этих трех строк может следовать описание функции main из программы 3.2. Этот код может быть сохранен в файле с именем, например, avg.c. Результатом совместной компиляции программ avg.c и int.c будут те же функциональные возможности, что и реализуемые программой 3.2. Но рассматриваемая реализация более гибкая, поскольку связанный с типом данных код инкапсулирован и может использоваться другими клиентскими программами, а также потому, что про-фамма avg.c без изменений может использоваться с другими типами данных. По-прежнему предполагается, что любой тип, используемый под именем Number, преобразуется в тип float. С++ позволяет описывать это преобразование, а также описывать желаемые встроенные операторы (подобные += и ) как часть нового типа данных. Повторное использование имен функций или операторов в различных типах данных называется перегрузкой (overloading). Помимо рассмотренного сценария клиент-интерфейс-реализация существует много других способов поддержки различных типов данных. Эта концепция выходит за рамки определенного языка профаммирования, либо метода реализации. Действительно, поскольку имена файлов не являются частью языка, возможно, придется изменить рекомендованный выще простой метод для функционирования в конкретной среде С++ (в системах существуют различные соглащения или правила, относящиеся к содержимому файлов заголовков, а некоторые системы требуют определенных расширений, таких как .С или .схх для файлов программ). Одна из наиболее важных особенностей С++ заключается в понятии классов, которые предоставляют удобный метод описания и реализации типов данных. В этой главе за основу взято простое решение, но впоследствии практически повсеместно будут использоваться классы. Глава 4 посвящена применению классов для создания базовых типов данных, что важно для разработки алгоритмов. Кроме того, подробно освещается взаимоотношение между классами С++ и парадигмой клиент-интерфейс-реализация . Главная причина существования этих механизмов состоит в обеспечении поддержки групп программистов, решающих задачи создания и содержания крупных систем приложений. Однако материал главы важен потому, что на протяжении книги используются механизмы создания естественных способов замены усовершенствованных реализаций алгоритмов и структур данных старыми методами. Это позволяет сравнивать различные алгоритмы для одних и тех же прикладных задач. Часто приходится создавать структуры данных, которые позволяют обрабатывать наборы данных. Структуры данных могут быть большими, либо иметь широкое применение. Поэтому необходима идентификация важных операций, которые будут выполняться над данными, а также знание методов эффективной реализации этих операций. Первые шаги выполнения этих задач заключаются в процессе последовательного создания абстракций более высокого уровня из абстракций низшего уровня. Этот процесс представляет собой удобный способ разработки все более мощных профамм. Простейшим механизмом группировки данных в С++ являются массивы (arrays), которые рассматриваются в разделе 3.2, и структуры (structures), о чем пойдет речь ниже. Структуры представляют собой сгруппированные типы, используемые для описания наборов данных. Этот подход позволяет управлять всем набором как единым модулем, при этом сохраняется возможность ссылаться на отдельные компоненты по именам. В языке С++ можно использовать структуру для описания нового типа данных, а также задавать операции для него. Другими словами, осуществимо управление сфуппированными данными почти так же, как встроенными типами, вроде int и float. Можно присваивать имена переменным и передавать эти переменные в качестве аргументов функций, а также выполнять множество других операций, как будет показано ниже. Программа 3.3 Интерфейс типа данных point Этот интерфейс описывает тип данных, состоящий из набора значений пары чисел с плавающей точкой и операции вычисление расстояния между двумя точками . struct point { float х; float у; }; float distance(point, point); При обработке геометрических данных используется абстрактное понятие точки на плоскости. Следовательно, можно ввести строку struct point { float х; float у; }; для указания, что имя point будет использоваться для ссылки на пары чисел с плавающей точкой. Например, выражение struct point а, b; объявляет две переменные этого типа. Можно ссылаться по имени на отдельные члены структуры. Например, операторы а.х = 1.0; а.у = 1.0; Ь.х = 4.0; Ь.у = 5.0; устанавливают значения переменных таким образом, что а представляет точку (1,1), а b - точку (4,5). Кроме того, можно передавать структуры функциям как аргументы. Например, код float distance(point а, point b) { float dx = a.x - b.x, dy = a.у - b.y; return sqrt(dx*dx + dy*dy); описывает функцию, которая вычисляет расстояние между двумя точками на плоскости. Это демонстрирует естественный способ использования структур для фуппиров-ки данных в типовых приложениях. Программа 3.3 содержит интерфейс, который воплощает описание типа данных для точек на плоскости: он использует структуру для представления точек и включает операцию вычисления расстояния между двумя точками. Программа 3.4 - это функция, которая реализует операцию. Подобная схема интерфейс-реализация используется для описания типов данных при любой возможности, поскольку в ней описание инкапсулировано (в интерфейсе), а реализация выражена в прямой и понятной форме. Тип данных используется в клиентской программе за счет включения интерфейса и компиляции реализации совместно с клиентом (либо с помощью функций раздельной компиляции). Программа реализации 3.4 включает интерфейс (про-
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |