Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 77
Текст из файла (страница 77)
Однако если бы смешанные выражения в языке С не допускались, то подобная ошибка была бы зарегистрирована компилятором как ошибка определения типа. В качестве примера более серьезной опасности и большей неэффективности, вызванной существованием слишком широкого приведения типов, рассмотрим усилия разработчиков языка РЫ!, направленные на достижение гибкости выражений. В этом языке строка символов может входить в одно выражение с переменной целого типа. Во время 2ез7 6.4. Преобразования типов выполнения программы в строке проводится поиск целочисленной величины.
Если в какой-либо величине обнаруживается десятичная точка, то величина считается приналлежашей к типу с плавающей точкой, после чего другой операнд приводится к этому типу, и результат считается величиной с плавающей точкой. Наблюдение за приведением— чрезвычайно затратный процесс, поскольку и проверки типов, и их преобразования должны производиться во время выполнения программы.
Оно также мешает обнаружить в выражениях программистские ошибки, поскольку бинарный оператор может смешивать операнд любого типа с операндом практически любого другого типа. Поскольку смешанные выражения снижают вероятность обнаружения ошибок, лва языка, Ада и Мог(о)а-2, допускают существование в выражениях весьма ограниченного числа смешанных операндов. Ни в одном из операторов этих языков не допускается смешивание операндов целого типа и типа чисел с плавающей точкой, за единственным исключением: оператор возведения в степень в языке Ада может принимать в качестве первого операнда оба типа, а в качестве второго — целый тип.
В обоих языках существует небольшое число допустимых видов смешивания типов, в основном относящихся к полтипам. В большинстве остальных распространенных языков ограничений на смешанные арифметические выражения нет. В языках С++ и зача существуют типы целых чисел, меньше типа 1пк. В языке С++ это типы сЬак и вЬокк 1пк, а в языке )ача — Ьуце, вЬокк и сЬаж Операнды этих типов приводятся к типу 1пк при применении к ним практически любого оператора.
Таким образом, пока переменные этих типов могут содержать данные, нельзя оперировать с такими данными без приведения их к большему типу. Рассмотрим, например, следующие команды языка1ача: Ьуге а, Ь, с; а = Ь+ с; Значение переменных Ь и с приводятся к типу 1пк, после чего выполняется целочисленное сложение, результат которого преобразовывается в тип Ьуке и присваивается переменной а. 6.4.2. Явное првобразование типов Большинство языков позволяют выполнять явное преобразование типов, как сужаюшее, так и расширяющее.
В некоторых случаях выдаются сообщения, прелупреждаощие о значительном изменении величины объекта вследствие сужаюшего преобразования типов. Языки Мобц1а-2 и Ада предусматривают операции явного преобразования типов, имеющие синтаксис вызовов функций. В языке Ада, например, можно ввести команду АЧО := ГЬОАТ(БОИ) / ГЬОАТ(СООХТ) Здесь переменная АЧО имеет тип с плавающей точкой, а ЯУН и СОО(ЧТ могут иметь л)обой числовой тип. В языках, основанных на языке С, явное преобразование типа называется приведением (сам). (На русский язык слова "сам" и "соегсюп" переводятся одинаково— "привеление", хотя происхождение этих терминов разное: "саз(" используется при описании языка С, а "соегсюп" — при описании языка АЬООЬ 68.
— Прин. ред.). Синтак- 2ВВ Глава 6. Выражения и опараторы присваивания «» приведения не совпадает с синтаксисом вызовов функций: требуемый тип помещаетс в круглые скобки непосредственно перед преобразовываемым выражением: хпц) апс)1е дчой из причин использования в языке С скобок при преобразованиях типов является ествование в этом языке имен типов.
состоящих из двух слов, например 1опа ьпц. 6.4.3. Ошибки в вырязжениях )1рн вычислении выражения может возникнуть множество ошибок. Если язык требу.- зроверки типов, то может возникнуть ошибка определения типов операндов. Ранее :,ждались ошибки, возникающие из-за приведения операндов в выражениях. Другие - ~ ошибок связаны с ограниченностью компьютерной арифметики и собственными — нпчениями арифметики.
Наиболее часто возникает ошибка, если невозможно пред- вить результат операции в предназначенной для него ячейке памяти. Такие ошибки '.ываются переполнением памяти и потерей значимости, в зависимости от того, являет.: ." зультат слишком большим или слишком маленьким. Одним из ограничений ариф»-,,ки является запрет деления на нуль. Однако то, что это деление не разрешено в ма. ' зтике, не мешает программе попытаться его выполнить.
:.ереполнение памяти и потеря значимости при работе с величинами с плавающей -."й. а также деление на нуль — все это примеры ошибок времени выполнения прочны. иногда называемых исключительными ситуациями. Способы, с помощью кото-.: х разработчики языка пытаются бороться с исключительными ситуациями.
рассмат- ззются в главе )3. 6.5. Выражения отношений и булевские выражения Помимо арифметических выражений, в языках программирования существуют еше гажения булевские, или логические. 6.5.1. Выражения отношения Оцерацал Равно Не равно Больше Раппам АсМа ГОМГМВАИ 77 .ЕО. .
))Е. .ОТ. 289 6.5. Выражения отношений и булевские выражения Оператор отношений (ге)айопа! орегагог) сравнивает значения двух своих операнз Выражение отношений (ге)айопа! ехргеиюп) состоит иэ лвух операндов и одного . -ератора отношений. Значение выражения отношений принадлежит к булевскому типу, : » кдючением случая, когда в языке нет булевского типа. Операторы отношений обычперегружаются для большого числа типов. Операшся, определяющая истинность или -с,кность выражения отношений.
зависит от типов операндов. Она может быть простой =зя целых операндов) или сложной (для операндов, являющихся символьными строка' »х Обычными типами операндов. которые могут использоваться в выражениях отно"сний. являются числовые типы, строки и порядковые типы. Ниже приводится синтаксис выражений отношения в некоторых распространенных стыках программирования. Меньше Больше или равно Меньше или равно < .ЬТ. >= .ОЕ.
<= .ЬЕ. Поскольку на карточных перфораторах времен разработки языка РОКТКАХ 1 отсутствовали символы < и >, то разработчики этого языка использовали в выражениях отношения соответствующие английские аббревиатуры. В языке РОКТЙАХ 90 допускается использование исходных операторов отношений и операторов, аналогичных существующим в языке Рааса!, за исключением того, что для отношения равенства используется символ ==. Приоритет операторов отношения всегда ниже приоритета арифметических операций, поэтому в выражениях а+1>2*)э первыми вычисляются арифметические выражения.
6.$.2. Булевские выражения Отметим, что булевские операторы языка Аг)а, кроме оператора поп, имеют одинаковый приоритет. Все эти операторы неассоциативны, поэтому для указания порядка вычисления булевских операторов лолжны использоваться скобки. Например, выражение: А > В епс( А < С ок К = О в языке Ада недопустимо.
Допустимым булет следующее: (А>Вепс)А<С) окК=О или такое: А > В апгз (А < С ог К = О) 290 Глава 6. Выражения и операторы присваивания Булевские выражения состоят из булевских переменных, булевских констант, выра- жений отношения и булевских операторов. В число последних обычно входят операции логических И, ИЛИ н НЕ, а иногда еше исключающего ИЛИ и эквивалентности. Булев- скне операторы обычно принимают только булевские операнлы (булевские переменные, булевские литералы или выражения отношения) и порождают булевские значения. В большинстве языков у булевских операторов, как и у арифметических, существует иерархия приоритетов выполнения. В большинстве распространенных языков програм- мирования операция унарного логического отрицания имеет наивысший приоритет, за ней следует операция логического И, а наименьший приоритет имеет операция логиче- ского ИЛИ.
Поскольку арифметические выражения могут быть операндами выражений отноше- ния, а выражения отношения могут быть операндами булевских выражений, то должны быть определены соотношения между приоритетами операторов трех этих категорий. Приоритеты операторов языка Аг)а располагаются следующим образом: Наивысший *', а)>в, поп *, (, жоа, (унарные) с (бинарные) /=, <, >, <=, >=, 1п, пос 1п Наименьший епс(, ок, хоп, еп<) с)зеп, ок е1ве ,;пользование данного выражения.
Операторы апе! сЬеп и ок е1ве языка Ада рас. и атриваются в следующем разделе. Среди императивных языков язык С отличается тем, что он не содержит булевского -ипа данных и, следовательно, булевских величин. Для представления булевских значе-ий в языке С используются целые значения. Вместо булевских операндов используются . ледовые переменные и константы, нулевое значение которых соответствует ложности, а .-.юбое другое — истинности. Таким образом, результатом вычисления такого выражения =вдаются целое число О в случае ложности и ! в случае истинности.
Необычным следствием структуры языка С является допустимость выражения а>Ь>с Поскольку операторы отношения языка С являются левоассоциативными, то первым вычисляется крайний слева оператор отношения, порождая О или !. Затем этот результат сравнивается с переменной с. Сравнения переменных Ь и с не происходит никогда. Иерархия приоритетов операторов в языках С и С++ с включенными в нее неарифметическими операторами насчитывает более 50 операторов и )7 уровней приоритетов. Это является явным доказательством изобилия наборов операторов и сложности выражений, возможных в этих языках.
Как уже говорилось в главе 5, с точки зрения читабельности язык должен содержать булевский тип данных и не использовать в булевских выражениях числовые типы. Поскольку в языке С любое числовое выражение, независимо от того, задумывалось это ~шн нет, может использоваться в качестве допустимого операнда булевского оператора, то в этом языке утеряны некоторые возможности обнаружения ошибок. В других же императивных языках любое небулевское выражение, использованное в качестве операнда б) левского оператора, будет воспринято как ошибка.