Главная » Просмотр файлов » М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)

М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781), страница 30

Файл №1160781 М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)) 30 страницаМ. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781) страница 302019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 30)

4. Напишите программу для печати двоичного представления десятичной дроби.

5. Напишите программу для BCD-арифметики.

6. Напишите программу для эмуляции сложения и умножения с плаваю­щей точкой.

7. Объявите различные типы с фиксированной точкой в Ada и проверьте, как представляются значения. Как представляется тип Duration?

8. В Ada существуют ограничения на арифметику с фиксированной точкой. Перечислите и обоснуйте каждое ограничение.

Глава 10

Полиморфизм

Полиморфизм означает «многоформенность». Здесь мы этим термином обозначаем возможность для программиста использовать переменную, значе­ние или подпрограмму двумя или несколькими различными способами. По­лиморфизм почти по определению является источником ошибок; достаточно трудно понять программу даже тогда, когда каждое имя имеет одно значение, и намного труднее, если имя может иметь множество значений! Однако во многих случаях полиморфизм необходим и достаточно надежен при аккурат­ном применении.

Полиморфизм может быть статическим или динамическим. В статическом полиморфизме множественные формы разрешаются (конкретизируются) на этапе компиляции, и генерируется соответствующий машинный код. Напри­мер:

• преобразование типов: значение преобразуется из одного типа в другой;

• перегрузка (overloading): одно и то же имя используется для двух или не­скольких разных объектов или подпрограмм (включая операции);

• родовой (настраиваемый) сегмент: параметризованный шаблон под­программы используется для создания различных конкретных экземпля­ров подпрограммы.

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

• вариантные и неограниченные записи: одна переменная может иметь значения разных типов;

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

10.1. Преобразование типов

Преобразование типов — это операция преобразования значения одного типа к значению другого типа. Существуют два варианта преобразования типов: 1) пе­ревод значения одного типа к допустимому значению другого типа, и 2) пере­сылка значения как неинтерпретируемой строки битов.

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

Ada

I: Integer := 5; F:

Float := Float(l);

в то время как синтаксис языка С может показаться странным, особенно в сложном выражении:

C


int i = 5;

float f = (float) i;

В C++ для совместимости сохранен синтаксис С, но для улучшения читаемо- сти программы также введен и функциональный синтаксис, как в Ada. Кроме того, и С, и C++ включают неявные преобразования между типами, прежде всего числовыми:

C

int i; float f = i;

Явные преобразования типов безопасны, потому что они являются всего

лишь функциями: если не существует встроенное преобразование типа, вы

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

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

Вторая форма преобразования типов просто разрешает программе исполь-зовать одну и ту же строку битов двумя разными способами. К сожалению, в языке С используется один и тот же синтаксис для обеих форм преобразова-ния: если преобразование типов имеет смысл, например между числовыми типами или указательными типами, то оно выполняется; иначе строка битов передается, как есть.

В языке Ada можно между любыми двумя типами осуществить не контролируемое преобразование (unchecked conversion), при котором значение трактуется как неинтерпретируемая строка битов. Поскольку это небезопасно по самой сути и разрушает все с таким трудом добытые преимущества контроля типов, неконтролируемые преобразования не поощряются, и син­таксис языка спроектирован так, чтобы такие преобразования бросались в глаза. При просмотре программы вы не пропустите места таких преобразова­ний и должны будете «оправдаться» хотя бы перед собой.

Хотя для совместимости в C++ сохранено такое же преобразование типов, как в С, в нем определен новый набор операций преобразования типов:

• dynamic_cast. См. раздел 15.3.

• static_cast. Выражение типа Т1 может статически приводиться к типу Т2, если Т1 может быть неявно преобразовано к Т2 или обратно; static_cast следует использовать для безопасных преобразований типов, как, напри­мер, float к int или обратно.

• reinterpret_cast. Небезопасные преобразования типов.

• const_cast. Используется, чтобы разрешить делать присваивания кон­стантным объектам.

10.2. Перегрузка

Перегрузка — это использование одного и того же имени для обозначения раз­ных объектов в общей области действия. Использование одного и того же имени для переменных в двух разных процедурах (областях действия) не рас­сматривается как перегрузка, потому что две переменные не существуют од­новременно. Идея перегрузки исходит из потребности использовать матема­тические библиотеки и библиотеки ввода-вывода для переменных различных типов. В языке С имя функции вычисления абсолютного значения свое для каждого типа.

C

int i =abs(25);

double d=fabs( 1.57);

long I =labs(-25L);

В Ada и в C++ одно и то же имя может быть у двух или нескольких разных под­программ при условии, что сигнатуры параметров разные. Пока число и/или типы (а не только имена или режимы) формальных параметров различны, компилятор будет в состоянии запрограммировать вызов правильной под­программы, проверяя число и типы фактических параметров:

function Sin(X: in Float) return Float;

function Sin(X: in Long_Float) return Long_Float;

Ada


F1,F2: Float;

L1.L2: Long_Float:

F1 :=Sin(F2);

L1 :=Sin(L2);

Интересное различие между двумя языками состоит в том, что Ada прини-мает во внимание тип результата функции, в то время как C++ ограничивает-ся формальными параметрами:

|с++

C++

float sin(float);

double sin(double); // Перегрузка sin

double sin(float); // Ошибка, переопределение в области действия

Особый интерес представляет возможность перегрузки стандартных опера­ций, таких как + и в Ada:

C++

I Ada function "+" (V1, V2: Vector) return Vector;

Конечно, вы должны представить саму функцию, реализующую перегру­женную операцию для новых типов. Обратите внимание, что синтаксические свойства операций, в частности старшинство, не изменяются. В C++ есть аналогичное средство перегрузки:

C++


Vector operator + (const Vector &, const Vector &);

Это совершенно аналогично объявлению функции, за исключением заре-

зервированного ключевого слова operator. Перегружать операции имеет смысл только в том случае, если вновь вводимые операции аналогичны предопределенным, иначе можно запутать тех, кто будет сопровождать про­грамму.

При аккуратном использовании перегрузка позволяет уменьшить длины имен и обеспечить переносимость программы. Она может даже уве­личить прозрачность программы, поскольку такие искусственные имена, как fabs, больше не нужны. С другой стороны, перегрузка без разбора мо­жет легко нарушить читаемость программы (если одному и тому же имени будет присваиваться слишком много значений). Перегрузка должна быть ограничена подпрограммами, выполняющими аналогичные вычисления, чтобы читатель программы мог понять смысл уже по самому имени подпро­граммы.

10.3. Родовые (настраиваемые) сегменты

Массивы, списки и деревья — это структуры данных, в которых могут хра­ниться элементы данных произвольного типа. Если нужно хранить несколько типов одновременно, необходима некоторая форма динамического полимор­физма. Однако если мы работаем только с гомогенными структурами данных, как, например, массив целых чисел или список чисел с плавающей точкой, достаточно статического полиморфизма, чтобы создавать экземпляры программ по шаблонам во времени компиляции.

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

Сложная обработка индексов делается одинаково для всех типов элементов массива:

type lnt_Array is array(lnteger range <>) of Integer;

procedure Sort(A: lnt_Array) is

Ada

Temp, Min: Integer;

Begin

for I in A'First ..A'Last-1 loop

Min:=l;

for J in I+1 .. A'Last loop

if A(J) < A(Min) then Min := J; end if;

-- Сравнить элементы, используя "<"

end loop;

Temp := A(l); A(l) := A(Min); A(Min) := Temp;

-- Переставить элементы, используя ":="

end loop;

end Sort;

На самом деле даже тип индекса не существенен при программировании этой процедуры, лишь бы он был дискретным типом (например, символьным или целым).

Чтобы получить процедуру Sort для некоторого другого типа элемента, на­пример Character, можно было бы физически скопировать код и сделать не­обходимые изменения, но это могло бы привести к дополнительным ошиб­кам. Более того, если бы мы хотели изменить алгоритм, то пришлось бы сде­лать эти изменения отдельно в каждой копии. В Ada определено средство, называемое родовыми сегментами (generics), которое позволяет программисту задать шаблон подпрограммы, а затем создавать конкретные экземпляры подпрограммы для нескольких разных типов. Хотя в С нет подобного средст­ва, его отсутствие не так серьезно, потому что указатели void, оператор sizeof и указатели на функции позволяют легко запрограммировать «обобщенные», пусть и не такие надежные, подпрограммы. Обратите внимание, что примене­ние родовых сегментов не гарантирует, что конкретные экземпляры одной родовой подпрограммы будут иметь общий объектный код; фактически, при реализации может быть выбран независимый объектный код для каждого конкретного случая.

Ниже приведено объявление родовой подпрограммы с двумя родовыми фор­мальными параметрами:

generic

Ada

type Item is (<>);

type ltem_Array is array(lnteger range <>) of Item;

procedure Sort(A: ltem_Array);

Это обобщенное объявление на самом деле объявляет не процедуру, а только шаблон процедуры. Необходимо обеспечить тело процедуры: оно будет напи­сано в терминах родовых параметров:

Ada

procedure Sort(A: ltem_Array) is

Temp, Min: Item;

begin

… -- Полностью совпадает с вышеприведенным

end Sort;

Чтобы получить (подлежащую вызову) процедуру, необходимо конкретизиро­вать родовое объявление, т. е. создать экземпляр, задав родовые фактические параметры:

Ada

type lnt_Array is array(lnteger range <>) of Integer;

type Char_Array is array(lnteger range <>) of Character;

Характеристики

Тип файла
Документ
Размер
2,54 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6358
Авторов
на СтудИзбе
311
Средний доход
с одного платного файла
Обучение Подробнее