Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 57
Текст из файла (страница 57)
Рассмотрим операцию присваивания А = В, где А и В— целые числа. В языке С, как и во многих других языках, это означает «присвоить копию значения переменной В переменной А» (то есть «присвоить йзначенпю объекта А г-значение объекта В»). Рассмотрим теперь операцию присваивания А = В, где А и  — переменные-указатели. Если  — это указатель, то г-значенне В является l-значением некоторого другого объекта данных.
Тогда это присваивание означает следующее: «сделать г-значение объекта А ссылкой на тот же самый объект, указателем иа который является г-значение объекта В». Иначе говоря, «присвоить йзначению объекта А г-значенис объекта В, которое является 1-значением некоторого другого объекта данных». Таким образом, присваивание А = В 5Д, Свойства типов и объектов 203 означает «присвоить копию указателя, хранящегося в переменной В, переменной А» (рис.
5.2), Операция числового присваивания в С *БЛ Ф в:[м 1 БЛ »1 После До Операция присваивания дпя уквзвтепей в С А.' В: В: До После Рис. 5.2. Два взгляда на операцию присваивания Равенство н эквивалентность. Оператор присваивания настолько распространен, что немногие задумываются о его семантике. Тем не менее существует один вопрос, требуюппнй разрешения. Рассмотрим присваивацпе значения обьекту А в некотором новом языке Лог)с: Я»-2»3 Эту запись можно интерпретировать двумя способами: 1) вы шсляется выражение 2 + 3 и его результат, то есть 5, присваивается А; 2) А присваивается целая операция 2» 3.
В тех языках, где данные имеют статически опрелсляемый тпп, способ интерпретапии зависит от типа об ьекта А. Если объект А определен как целое число, то имеет смысл только первая интерпретация; если же объект А определен как объект типа операция, то следует выбрать вторую интерпретацшо. Но в языках с динамическим определением типов, когда тип обьекта А задаемся посредством присвоения этому объекту какого-либо значения, допустимы обе интерпретации, и, следовательно, приведенная выше операция присваивания становится неоднозначной.
Именно такая ситуация возникает в языке Рго1оя. Операция 33 означает присваиванис эквивалентного значения, в то время как операция = обозначает присваивание образца. Тогда равенство определяется в зависимости от текущего зна- 204 !пава 5. Элементарные типы данных чения, присвоенного переменной. Рассмотрим следуя>щие две последовательности операпий языка Рго!ой: Х гл 2 + 3.
Х = 5 Х - 2 + 3 Х = 5 Первая послггдовательность правильная, так как сначала переменной Х присваивается значешзс 5 и се тип устанавливается как целочисленный, в то время как во второй последовательности переменной Х сначала присваивается операция 2 - 3— отнюдь не то же самое, что целое число 5. Заметим, что в данном случае символ = используется в зависимости от контекста как для обозначения операции присваивания, так и для обозначения операции логического сравнения.
Фактически здесь приведен пример использования принципа унификации, что характерно для языка Рго1оя (присваиваггив и 2 > 3, и 5 объекту Х во второй последовательности операций взаимно несовместимо). В дальнейшем мы поясн>гм это в разделе 8.4.3. Инициализация. Неиггициагази7юаанггал не)ггмгенггал, или, более обобгцеи но, неигщциализировагщогй обьелт данных, — это такой объект, который был создан, но которому еще не было присвоено значение (иначе говоря, йзначен ие без соответствующего г'-значения). Создание объекта данных обычно только подразумевает выделение блока памяти для этого объекта.
Если далее не предпринимается никаких действий, то в этом блоке памяти остается гаже комбинация битов, которая была там на момент создания объекта. Обычно для связывания объекта данных с каким-либо допустимым значением требуется явная операция присваивания. В некоторых языках (например, в Разса1) инициализация должна производиться явным образом, посредством операций присваивания. В других языках (>>а>гриме!х в АР1.) при создании объекта данных необходимо сразу же задать его исходное значение, причем это щюисходит неявным образом, без исгголлзоваггия программистом оператора присваивания. Не ни ициализирован и ы е переменные являются серьезным источником ошибок как для новичков, так и для профессионалов. Случайная конфигурация битов, содержащаяся в области, отведешюй под значение неинициализированного объекга данных, по существу, неотли щма от настоящего значения, которое также представляет собой некоторую конфигурацию битов.
Таким образом, программа может использовать в вычислениях такое случайное лзначсниеи неинициализированной переменной, и хотя ее работа может выглядеть правильной, по существу, в пей будет содержаться серьезная ошибка. Такое влияние на надежность программы неинициализированных переменных привело к тому, что, как правило, переменные принято инициализировать непосредственно при их создании путем присвоения им начальных значений, и в современных языках, например в Ас1а, предусмотрены механизмы, которые облегчают эту задачу. В АХ!а каждое объявление переменных может вклгочать в себя также присваивацие этой переменной начального значения, при этом используется синтаксис обычной операции присваивания.
В частности, обьявление А. аггау(1. 31 от Поаг .= 117.2. 20 Х, 23 61, создаст массив А и явным образом присваивает каждому элементу массива начальное значение. Поскольку обычно массив создается динамически в процессе выполнения программы, реализация присваивания начальных значений требует генерации компилятором кола, который при выполнении программы явным образом присваивает указанные начальные значения объекту данных. 5.2. Скалярные типы данных 205 5.2.
Скалярные типы данных Сначала мы рассмотрим класс элементарных объектов данных, называемый скалярными обьекнгами данных. Этот тип характеризуется тем, что у каждого объекта имеется только один атрибут. Например, для целочисленного объекта единственным атрибутом является его значение (например, н 3, 42) и никакой другой информации в этом объекте не содержится. Далее, в разлсле 5.3, мы рассмотрим более сложные, составные объекты ланных, у которых может иметься несколько атрибутов. Например, строка символов содержит последовательность символов (значение объекта), а дополнительным атрибутом может являться ес длина, то есть количество спмволов в строке. Вообще, скалярные объекты данных (целых чисел, чисел с плавающей точкой, символов) тесно связаны с архитектурой аппаратной части компьютера, а составные объекты (цапрнмер, строки) обычно представляют собой более сложные структуры, создаваемые компилятором, и не являются элементарными объектами, реализуемыми в аппаратной части компьютера.
5.2.1. Численные типы данных Почти в любом языке программирования присутствуют в той или иной форме пифровые (численные) типы данных. Наиболее распространенными являются целочисленный и вещественный типы, так как они обычно поддерживаются аппаратной частью компьютера. Компьютерное представление числовых данных и реализация арифметических операций над пилш сильно отличаются от чисел и операций, используемых в обычной математике. Компьютерная арифметика -- это отдельный и очень увлекательный предмет, которому посвящены мцопгс книги; но он не является центральным для понимания общей структуры языков программирования, поэтому здесь мы приводим только краткий обзор по данной теме. Целые числа Спецификация. Множество чисел этого типа образует ограниченное упорялоченное подмножество бесконечного множества целых чисел, определенного в математике.
Максимальное значение иногда определяется как именованная константа (например, в Раэса! имеется константа паха по). В таком случае обычно все множествоо допустимых значений целых чисел заключено в диапазоне между числами гпахапг и глахапс Как было сказано ранее, в языке С имеются четыре подтипа целочисленных объектов: ало, звог~, 1олц и сваг. Операции над целочисленными объектами данных обычно разделяются на следующие основные группы. + А рифмегпические операции.
Снгпатура бинарных арифметических операций такова: БлнОп целое х целое -а целое Здесь БлнОп может бьггь сложением (+), вычитанием ( — ), умножением (х), делением (У или гй ц), а также делением по модулю (поС) или сивкой операцией. Унарные операции имегот следукппую сигнатуру: уларСп . целое -а пегое 206 Глава 5. Элементарные типы данных где унарбл может быть, например, операцией отрицания (-) или идентичности (.ь). Обычно включаются и другие арифметические операции, часто в виде библиотечных подпрограмм-функций (например, операция определения абсолютттого значения). + Операции сравнения. Сигнатура любой операции сравнения выглядит следующим образом: Соавоп : целое х целое -т булева Здесь под Сравбп могут подразумеваться следующие операции; равно, не равно,больше чем,меньше чем,больше нлн равно, меньше нлн равно.
Операция сравнентия сравнивает значения двух переданных ей аргументов и в качестве результата возвраптает логический (булев) объект данных. + ОгтераЧии присеииеакия Присваивание для целочисленных объектов можно определить одним из двух способов; прнсваивание целое х целое -т пустой тнп или присванванне целое х целое -т целое Этот вопрос уже обсуждался в предыдушем разделе. + Битовые операции. В языках с неболыпим количеством элементарных типов данных целые числа выполняют множество разнообразных функций. В С, напртимер, они используются в качестве булевых величин.