И.Г. Головин, И.А. Волкова - Языки и методы программирования, страница 10
Описание файла
PDF-файл из архива "И.Г. Головин, И.А. Волкова - Языки и методы программирования", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 10 страницы из PDF
далее). Обратим внимание, что равенство задается символами«==», так как символ «=» занят операцией присваивания (эти операции могут смешиваться в выражениях, поэтому необходимо различатьих лексически).Кроме перечисленных операций существуют операции с побочным эффектом (изменяющие операнд и вычисляющие значение):• префиксный инкремент ++х (увеличение на единицу, возвращаетсяновое значение х);• постфиксный инкремент х++ (увеличение на единицу, возвращается старое значение х);• префиксный декремент —х (уменьшение на единицу, возвращается новое значение х);• постфиксный декремент х— (уменьшение на единицу, возвращается старое значение х);Присваивание также является операцией:v = е44Эта операция вычисляет значение выражения е и присваиваетего правой части v. Если типы v и е различные, то транслятор либовставляет неявное преобразование к типу правой части v, либовыдает сообщение об ошибке (если язык запрещает такое преобразование).
Присвоенное значение будет значением операции присваивания. Ассоциативность операции присваивания справа налево,в отличие от операций, приведенных ранее.Для двуместных операций (таких, как сложение, сдвиги и томуподобных) определена комбинированная операция присваивания,например:v += еКак и обычное присваивание, эта операция вычисляет значение е(возможно с приведением типа), а затем увеличивает значение v навычисленное значение. Новое значение v будет значением комбинированной операции.Возникает следующий вопрос: есть ли в этих языках операторприсваивания? Непосредственно такого понятия нет (так как присваивание — это операция, а не оператор).
Однако в этих языкахесть понятие «оператор-выражение». Оператор-выражение — этолюбое корректное выражение, после которого поставлена точкас запятой:ехрг ;Поэтому в роли оператора присваивания выступает, напримерследующая конструкция:i = х + у;Конечно, присваивание может случиться и в других контекстах.Вещественные типы данныхВещественные типы данных служат для представления числовыхдробных значений.Большинство языков использует для хранения таких чисел форматс плавающей точкой и основанием 2. Значение числа представляетсяв виде(_l)s * м*2Ргде S — бит знака (0 соответствует «+», а 1 — «-»); м — нормализованная мантисса (1 <= м < 2); р — порядок.За счет нормализованное™ мантиссы число всегда представляетсяединственным образом (заметим, что нормализованность мантиссыозначает, что старший ее бит всегда 1, поэтому эту единицу хранитьне надо, т.е.
она подразумевается).45Языки C++, C# и Java содержат два плавающих типа: f l o a tИ double.Как и для целых типов, язык C++ не фиксирует конкретный формат представления чисел, можно только сказать, чтоs i z e o f (float) <= s i z e o f (d o u b le)Языки C# и Java поддерживают один и тот же формат представления чисел, который определяется международным стандартом IEEE754 [36]. Этот стандарт определяет базовые форматы представленияплавающих чисел и правила выполнения арифметических операцийнад ними. Несмотря на добровольный характер этого стандарта практически все современные архитектуры (в том числе архитектуры х86и JVM) поддерживают его требования. Краткое описание стандартаможно найти в приложении к [29].
В языке Java (и спецификацииJVM) форматы плавающих типов и операции с плавающими типамиполностью соответствуют стандарту.Стандарт IEEE-754 определяет два базовых формата чисел с плавающей точкой: с одинарной (32 бит) и двойной (64 бит) точностью.Формату одинарной точности соответствует тип flo a t, а форматудвойной точности — dou b le.В формате одинарной точности один бит занимает знак, 23 бит —мантисса, 8 бит — порядок.
В формате двойной точности мантиссазанимает 52 бит, порядок — 11 бит.Два значения порядка (максимальное и минимальное) используются для представления специальных значений.Легко вычислить минимальное (по абсолютной величине) и м аксимальное значения типа float (учитывая, что старший бит мантиссывсегда 1, и он не хранится):MAX_FLOAT= (1-2“24)*2127; MIN_FLOAT=l/2*2 2'126Аналогичные значения можно вычислить для двойной точности.Самое важное, что следует помнить про плавающие типы, этото, что арифметические вычисления над ними неточные, и ошибкавычислений является относительной.
Так, для типа flo a t точностьсложения составляет 2~23, если операнды находятся между 1 и 2, однако для операндов порядка 224 точность уже порядка 1.Следовательно, задачи с большим объемом вычислений с плавающей точкой требуют применения специальных алгоритмов, устойчивых к погрешностям вычислений и входных данных.Однако некоторые приложения требуют вычислений с фиксированной точностью, которая не зависит от абсолютной величиныоперандов (типичный пример — финансовые вычисления).
Эти вычисления требуют представления дробных чисел с фиксированнымчислом знаков в дробной части.Типы данных с таким представлением называются фиксированными.46Языки C++ и Java не содержат в базисе таких типов. Их приходитсямоделировать с помощью механизма классов.Язык C# содержит специальный тип d e c im a l, который служитдля фиксированного представления чисел с дробной частью (такжеон может представлять целочисленные значения, не представимыецелыми типами). Размер значений типа d e c im a l 128 бит. В ниххранятся бит знака S , коэффициент с (0 < с < 296) и масштаб е(О <= е <= 2 8).
Значение определяется формулой(-1)3 * с * 1(ГеТаким образом, минимальное (по абсолютной величине) значениесоставляет 10“29, а максимальное — приблизительно 7 .9 * 1028.Точность представления 28-29 десятичных цифр.Такой тип подходит и для финансовых расчетов, и для ряда другихприложений, требующих абсолютной погрешности в вычислениях.Операции над вещественными числами включают в себя базовыйарифметический набор (сложение, вычитание, умножение и деление),а также операции сравнения (при этом надо помнить, что в силупогрешностей вычислений операция сравнения на равенство можетдавать неожиданные результаты).Символьные типы данныхСимвольные типы данных служат для следующих представлений:• символов (литер) алфавитов естественных языков;• символов, управляющих работой устройств ввода-вывода (например, символов перехода на новую строку, табуляции и т.п.);• специальных символов (валютного знака).Каждый символ имеет свое название (например, «возврат каретки», «маленькая кириллическая буква я», «знак копирайта»).
Символьные типы основаны на понятии множества символов (characterset).М нож ество символов определяет, во-первых, набор символов,а во-вторых, кодировку этого набора — отображение набора на диапазон целых чисел. Значения символьного типа — это и есть значенияиз этого диапазона.Таким образом, символы могут представляться целым типомданных, что и было принято в ряде языков программирования.Например, в языке С целый тип char использовался для представления символов. «По наследству» такое представление перешло и вязык C++. Однако отсутствие специального типа для представлениясимволов снижает надежность программ, обрабатывающих текстовуюинформацию (а удельный вес таких программ в индустрии программирования постоянно возрастает).47В самом деле, если применение арифметических операций наподобие вычитания кода одного символа из кода другого символаили сложения кода символа с константой вполне допустимо, топеремножение, деление кодов и тому подобные операции, вполнедопустимые для целых типов, бессмысленны (а значит, ошибочны)для символьных типов.
Поэтому современные языки программирования определяют отдельный символьный тип, несовместимыйс целыми типами (хотя значения этого типа, конечно, представляютсобой целые числа).С символьными типами связана проблема представления произвольных множеств символов.
Ранние языки программирования (каки виртуальные архитектуры, на которых они основывались) использовали однобайтовые множества символов. В этих множествах числоразличных символов не превосходило двух с небольшим сотен (а прииспользовании только английского алфавита хватало и 127 различныхсимволов), поэтому для представления символа хватало одного байта(вспомним, что размер типа c h a r в языке С один байт).Однобайтовые множества символов породили ряд проблем.Первая проблема состояла в невозможности представления объемных иероглифических алфавитов (китайского, японского и др.).Вторая проблема заключалась в том, что однобайтовое множество по отдельности покрывает небольшое множество алфавитов.Исторически сложилось так, что почти каждое множество символовсодержит общий для всех набор, включающий в себя управляющиесимволы, символы английского алфавита, цифры, знаки препинанияи т.
п. Коды символов из этого набора соответствуют американскомустандарту ASCII-7 и принимают значения в диапазоне от 0 до 127.Остальные 128 символов в однобайтовой кодировке заполняютсясимволами других алфавитов. Очевидно, что даже европейские алфавиты предоставляют существенно больший набор символов. Поэтомупришлось разрабатывать множества символов отдельно для западноевропейских языков, кириллицы, турецкого, арабского, греческогои других языков. Можно представить, какие проблемы возникалипри создании программ, одновременно обрабатывающих тексты наразных языках (например, на русском, французском и турецком).Третьей проблемой стало обилие кодировок даже для одного алфавита (для русского набора символов в настоящее время широкоиспользуются по меньшей мере четыре однобайтовые кодировки).Ситуация изменилась после появления в 1991 г.
универсальногомножества символов UNICODE, содержащего символы почти всехреально используемых алфавитов. Символов достаточно много (тысячи), поэтому каждый из них кодируется двухбайтовым числом беззнака (промежуток от 0 до 65 535). Для каждого алфавита выделенсвой диапазон символов, например, кириллица находится в промежутке от 1040 (большая буква А) до 1298 (буква JJ — большаябуква J1 с крючком).48Почти все язы ки, появивш иеся после 1991 г., использую тUNICODE.Тип c h a r в языках Java и C# тоже использует это множество символов. Множество операций над типом включает в себя операциисравнения (в соответствии с кодировкой UNICODE), присваиванияи операцию «+» сцепления со строкой. Например, строка s получитзначение " l i n e 1" в следующем фрагменте:c h a r с = 11 ' ;s t r i n g s = " l i n e " + с;Значения типа c h a r могут неявно приводиться к целым типамданных, если это безопасно (например, могут приводиться к i n t ,и не могут приводиться к b y te ), поэтому в следующем фрагментеоперация «+» обозначает операцию сложения целых чисел:ch ar с = ' х ';i n t к = х + 1; / / то же самое, что и ( i n t ) x + 1Обратная операция преобразования (приведение целых значенийк символьному типу) допустима только явно:s b y te b = -1 ;ch ar с = (c h a r)b ;При этом корректность преобразования в языке C# контролируется при включении операции в checked-блок.В языке C++, как уже говорилось, символьные типы рассматриваются как целочисленные.