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

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

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

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

Подтипы важны для определения массивов, как это будет рассмотрено в раз­деле 5.4. Кроме того, именованный подтип можно использовать для упроще­ния многих операторов:

if С in Upper-Case then ... - Проверка диапазона

for C1 in Upper-Case loop ... — Границы цикла

4.6. Производные типы

Вторая интерпретация отношения между двумя аналогичными типами состо­ит в том, что они представляют разные типы, которые не могут использовать­ся вместе. В языке Ada такие типы называются производными (derived) типами и обозначаются в определении словом new:

type Derived_Dharacter is new Character;

C: Character;

D: Derived_Character;

С := D: -- Ошибка, типы разные

Когда один тип получен из другого типа, называемого родительским (parent) типом, он наследует копию набора значений и копию набора операций, но ти­пы остаются разными. Однако всегда допустимо явное преобразование между типами, полученными друга из друга:

D := Derived_Character(C); -- Преобразование типов

С := Character(D); -- Преобразование типов

Можно даже задать другое представление для производного типа; преобразо­вание типов будет тогда преобразованием между двумя представлениями (см. раздел 5.8).

Производный тип может включать ограничение на диапазон значений родительского типа:

type Upper_Case is new Character range 'A'.. 'Z';

U: Upper_Case;

C: Character;

С := Character(U); -- Всегда правильно

U := Upper_Case(C); -- Может привести к ошибке

Производные типы в языке Ada 83 реализуют слабую версию наследования (weak version of inheritance), которая является центральным понятием объект­но-ориентированных языков (см. гл. 14). Пересмотренный язык Ada 95 реали­зует истинное наследование (true inheritance), расширяя понятие производ­ных типов; мы еще вернемся к их изучению.

Целочисленные типы

Предположим, что мы определили следующий тип:

type Altitudes is new Integer range 0 .. 60000;

Это определение работает правильно, когда мы программируем моделирова­ние полета на 32-разрядной рабочей станции. Что случается, когда мы пере­дадим программу на 16-разрядный контроллер, входящий в состав бортовой электроники нашего самолета? Шестнадцать битов могут представлять целые числа со знаком только до значения 32767. Таким образом, использование производного типа было бы ошибкой (так же, как подтипа или непосред­ственно Integer) и нарушило бы программную переносимость, которая явля­ется основной целью языка Ada.

Чтобы решать эту проблему, можно задать производный целый тип без яв­ного указания базового родительского типа:

type Altitudes is range 0 .. 60000;

Компилятор должен выбрать представление, которое соответствует требуемо­му диапазону — integer на 32-разрядном компьютере и Long_integer на 16-раз­рядном компьютере. Это уникальное свойство позволяет легко писать на языке Ada переносимые программы для компьютеров с различными длинами слова.

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

I: Integer;

A: Altitude;

А := I; -- Ошибка, разные типы

А := Altitude(l); -- Правильно, преобразование типов

Таким образом, существует неизбежный конфликт:

• Подтипы потенциально ненадежны из-за возможности писать смешан­ные выражения и из-за проблем с переносимостью.

• Производные типы безопасны и переносимы, но могут сделать програм­му трудной для чтения из-за многочисленных преобразований типов.

4.7. Выражения

Выражение может быть очень простым, состоящим только из литерала (24, V, True) или переменной, но может быть и сложной комбинацией, включающей операции (в том числе вызовы системных или пользовательских функций). В результате вычисления выражения получается значение.

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

Значение литерала — это то, что он обозначает; например, значение 24 — целое число, представляемое строкой битов 0001 1000. Значение переменной V — содержимое ячейки памяти, которую она обозначает. Обратите внимание на возможную путаницу в операторе:

V1 :=V2;

V2 — выражение, значение которого является содержимым некоторой ячейки памяти. V1 — адрес ячейки памяти, в которую будет помещено значение V2.

Более сложные выражения содержат функцию с набором параметров или операцию с операндами. Различие, в основном, в синтаксисе: функция с па­раметрами пишется в префиксной нотации sin (x), тогда как операция с опе­рандами пишется в инфиксной нотации а + b. Поскольку операнды сами мо­гут быть выражениями, можно создавать выражения какой угодно сложности:

a + sin(b)*((c-d)/(e+34))

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

max (sin (cos (x)), cos (sin (y)))

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

Инфиксной нотации присущи свои проблемы, а именно проблемы стар­шинства и ассоциативности. Почти все языки программирования придержива­ются математического стандарта назначения мультипликативным операциям («*», «/») более высокого старшинства, чем операциям аддитивным («+», «-»), старшинство других операций определяется языком. Крайности реализованы в таких языках, как АР L, в котором старшинство вообще не определено (даже для арифметических операций), и С, где определено 15 уровней старшинства! Час­тично трудность изучения языка программирования связана с необходимостью привыкнуть к стилю, который следует из правил старшинства.

Примером неинтуитивного назначения старшинства служит язык- Pascal. Булева операция and рассматривается как операция умножения с высоким старшинством, тогда как в большинстве других языков, аналогичных С, ее приоритет ниже, чем у операций отношения. Следующий оператор:

pascal


if а > b and b > с then ...

является ошибочным, потому что это выражение интерпретируется

Pascal

if а > (b and b) > с then . . .

и синтаксис оказывается неверен.

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

C

inti=6, j = 7, k = 3;

i = i * j / k; /* результат равен 1 2 или 1 4? */

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

C

I=(i*j)/k

в то время как унарные операции группируются справа налево: !++i в языке С вычисляется, как ! (++i).

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

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

(а + Ь) + с + (d + е)

не определено, вычисляется а + b раньше или позже d + е, хотя с будет просум­мировано с результатом а + b раньше, чем с результатом d + е. Порядок может играть существенную роль, если выражение вызывает побочные эффекты, т. е. если при вычислении подвыражения происходит обращение к функции, ко­торая изменяет глобальную переменную.

Реализация

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

Выражения вычисляются изнутри наружу; например, а * (b + с) вычисля­ется так:

load R1,b

load R2, с

add R1 , R2 Сложить b и с, результат занести в R1

load R2, а

mult R1.R2 Умножить а на b + с, результат занести в R1

Можно написать выражение в форме, которая делает порядок вычисления явным:

явным:

bс + а

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

Эта форма называется польской инверсной записью (reverse polish notationRPN) и может использоваться компилятором. Выражение переводится в RPN, и затем компилятор вырабатывает команды для каждого операнда и опе­рации, читая RPN слева направо..

Для более сложного выражения, скажем:

(а + b) * (с + d) * (е + f)

понадобилось бы большее количество регистров для хранения промежуточ­ных результатов: а + b, с + d и т. д. При увеличении сложности регистров не хватит, и компилятору придется выделить неименованные временные пере менные для сохранения промежуточных результатов. Что касается эффектив ности, то до определенной точки увеличение сложности выражения дает луч­ший результат, чем использование последовательности операторов присваи­вания, так как позволяет избежать ненужного сохранения промежуточных ре­зультатов в памяти. Однако такое улучшение быстро сходит на нет из-за необ­ходимости заводить временные переменные, и в некоторой точке компиля­тор, возможно, вообще не сможет обработать сложное выражение.

Оптимизирующий компилятор сможет определить, что подвыражение а+b в выражении

(а + b) * с + d * (а + b)

нужно вычислить только один раз, но сомнительно, что он сможет распознать это, если задано

(а + b) * с + d * (b + а)

Если общее подвыражение сложное, возможно, полезнее явно присвоить его переменной, чем полагаться на оптимизатор.

Другой вид оптимизации — свертка констант. В выражении:

2.0* 3.14159* Radius

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

C

PI: constants 3.1 41 59;

Two_PI: constant := 2.0 * PI;

Circumference: Float := Two_PI * Radius;

4.8. Операторы присваивания

Смысл оператора присваивания:

переменная := выражение;

состоит в том, что значение выражения должно быть помещено по адресу па­мяти, обозначенному как переменная. Обратите внимание, что левая часть оператора также может быть выражением, если это выражение можно вычис­лить как адрес:

Ada

a(i*(j+1)):=a(i*j);

Выражение, которое может появиться в левой части оператора присваивания, называется l-значением; константа, конечно, не является 1-значением. Все вы­ражения дают значение и поэтому могут появиться в правой части оператора присваивания; они называются r-значениями. В языке обычно не определяет­ся порядок вычисления выражений слева и справа от знака присваивания. Ес­ли порядок влияет на результат, программа не будет переносимой.

В языке С само присваивание определено как выражение. Значение конструкции

переменная = выражение;

такое же, как значение выражения в правой части. Таким образом,

C


int v1 , v2, v3;

v1 = v2 = v3 = e;

означает присвоить (значение) е переменной v3, затем присвоить результат переменной v2, затем присвоить результат переменной v1 и игнорировать ко­нечный результат.

В Ada присваивание является оператором, а не выражением, и многократ­ные присваивания не допускаются. Многократное объявление

V1.V2.V3: Integer :=Е;

рассматривается как сокращенная запись для

Ada

V1 : Integer :=E;

V2: Integer := Е;

V3: Integer := Е;

а не как многократное присваивание.

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

C

If (i=j)...

программист, возможно, хотел просто сравнить i и j, не обратив внимания, что значение i изменяется оператором присваивания. Некоторые С-компиляторы расценивают это как столь плохой стиль программирования, что выдают пре­дупреждающее сообщение.

Полезным свойством языка С является комбинация операции и присваи­вания:

C


v+=e; /* Это краткая запись для... */

v = v + е; /* такого оператора. */

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

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

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

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