Явные преобразования указателей

Разрешаются определенные преобразования с использова-нием указателей. Они имеют некоторые зависящие от конкрет-ной реализации аспекты. Все эти преобразования задаются спомощью операции явного преобразования типа. Указатель может быть преобразован в любой из целочис-ленных типов, достаточно большой для его хранения. Требуетсяли при этом int или long, зависит от конкретной машины (в ОСДЕМОС для СМ ЭВМ требуется int). Преобразующая функциятакже является машинно-зависимой, но она будет вполнеестественной для тех, кто знает структуру адресации вмашине. Детали для некоторых конкретных машин приводятсяниже. Объект целочисленного типа может быть явным образомпреобразован в указатель. Такое преобразование всегда пере-водит преобразованное из указателя целое в тот же самый ука-затель, но в других случаях оно будет машинно-зависимым. Указатель на один тип может быть преобразован в указа-тель на другой тип. Если преобразуемый указатель не указы-вает на объекты, которые подходящим образом выравнены впамяти, то результирующий указатель может при использованиивызывать ошибки адресации. Гарантируется, что указатель наобъект заданного размера может быть преобразован в указательна объект меньшего размера и снова обратно, не претерпев приэтом изменения. Например, процедура распределения памяти alloc могла быпринимать запрос на размер выделяемого объекта в байтах, авозвращать указатель на символы; это можно было бы использо-вать следующим образом. -48- extern char * alloc (); double *dp; dp =(double*) alloc (sizeof (double)); *dp =22.0/7.0; Функция alloc должна обеспечивать (машинно-зависимым спосо-бом), что возвращаемое ею значение будет подходящим для пре-образования в указатель на double; в таком случае использо-вание этой функции будет переносимым. Представление указателя на CM-ЭВМ соответствует 16-битовому целому и измеряется в байтах. Объекты типа char неимеют никаких ограничений на выравнивание; все остальныеобъекты должны иметь четные адреса.

* 11. КОНСТАНТНЫЕ ВЫРАЖЕНИЯ

В нескольких местах в языке Си требуются выражения,которые после вычисления становятся константами: после вари-антного префикса case, в качестве границ массивов и в иници-ализаторах. В первых двух случаях выражение может содержатьтолько целые константы, символьные константы и выражения sizeof, возможно связанные либо бинарными операциями + - * /. % & | ^ << >> == 1= < > <= > = либо унарными операциями - ~ либо тернарной операцией ?: Круглые скобки могут использоваться для группировки, но недля обращения к функциям. В случае инициализаторов допускается большая (ударениена букву о) свобода; кроме перечисленных выше константныхвыражений можно также применять унарную операцию & к внешнимили статическим объектам и к внешним или статическим масси-вам, имеющим в качестве индексов константное выражение.Унарная операция & может быть также применена неявно, врезультате появления неиндексированных массивов и функций.Основное правило заключается в том, что после вычисленияинициализатор должен становится либо константой, либо адре-сом ранее описанного внешнего или статического объекта плюсили минус константа.

* 12. СООБРАЖЕНИЯ О ПЕРЕНОСИМОСТИ

Одним из достоинств языка Си считается переносимостьпрограмм на Си, которая связана как с относительной машинной -49- независимостью самого языка, так и с совместимостью среды,обеспечиваемой совместимыми с ОС UNIX операционными систе-мами. Вместе с тем, при написании на языке Си таких прог-рамм, которые не должны зависеть от конкретной ЭВМ, необхо-димо учитывать то, что некоторые части языка Си по своейсути машинно-зависимы. Следующее ниже перечисление потенци-альных трудностей хотя и не являются всеобъемлющими, новыделяет основные из них. Вопросы, целиком связанные с аппаратным оборудованием,такие как размер слова, свойства вещественной арифметики ицелого деления, не представляют особенных затруднений. Дру-гие аспекты аппаратных средств находят свое отражение в раз-личных реализациях. Некоторые из них, в частности, знаковоерасширение (преобразующее отрицательный символ в отрицатель-ное целое) и порядок, в котором помещаются байты в слове,представляют собой неприятность, которая должна тщательноотслеживаться. Большинство остальных проблем этого типа невызывает сколько_нибудь значительных затруднений. Число переменных типа register, которое фактическиможет быть помещено в регистры, меняется от машины к машине,также как и набор допустимых для них типов. Тем не менее всекомпиляторы на своих машинах работают надлежащим образом;лишние или недопустимые регистровые описания игнорируются. Некоторые трудности возникают только при использованиисомнительной практики программирования, или при использова-нии особенностей конкретной реализации. Писать программы,которые зависят от таких особенностей, чрезвычайно нера-зумно. Языком не указывается порядок вычисления аргументовфункций; они вычисляются справа налево на CM-ЭВМ и ЭВМ PDP -11 и VAXR-11 фирмы DEC и слева направо на большинствеостальных машин. Порядок, в котором происходят побочныеэффекты, также не специфицируется. Так как символьные константы в действительности явля-ются объектами типа int, допускается использование символь-ных констант, состоящих из нескольких символов. Однако, пос-кольку порядок, в котором символы приписываются к слову,меняется от машины к машине, конкретная реализация оказыва-ется весьма машинно_зависимой. Порядок присваивания полей к словам и символов к целымтакже зависит от ЭВМ. Такие различия незаметны для изолиро-ванных программ, в которых не разрешено смешивать типы (пре-образуя, например, указатель на int в указатель на char изатем проверяя указываемую память), но должны учитыватьсяпри согласовании с накладываемыми извне схемами памяти. -50- Язык, принятый на различных компиляторах, отличаетсятолько незначительными деталями. Самое заметное отличие сос-тоит в том, что используемый в настоящее время компилятор наCM-ЭВМ не инициализирует структуры, которые содержат полябитов, не имеет типа "unsigned char " и имеет некоторые огра-ничения на операции присваивания в определенных контекстах,связанных с использованием значения присваивания структур.

Анахронизмы

В старых программах можно встретить некоторые устарев-шие конструкции. Хотя большинство версий компилятора поддер-живает такие анахронизмы, они в конце концов исчезнут, оста-вив за собой только проблемы переносимости. В ранних версиях Си для проблем присваивания использо-валась форма = оп, а не оп =, приводя к двусмысленностям,типичным примером которых является х =-1 где х фактически уменьшается, поскольку операции = и - при-мыкают друг к другу, но что вполне могло рассматриваться икак присваивание -1 к х. Синтаксис инициализаторов изменился: раньше знакравенства, с которого начинается инициализатор, отсутство-вал, так что вместо int х = 1; использовалось int х 1; изменение было внесено из_за инициализации int f (1+2) которая достаточно сильно напоминает определение функции,чтобы смутить компиляторы.

* 13. СТАНДАРТНАЯ БИБЛИОТЕКА ВВОДА И ВЫВОДА

Средства ввода/вывода не являются составной частьюязыка Си. В этой главе будет описана "стандартная библио-тека ввода/вывода", то есть набор функций, разработанных дляобеспечения стандартной системы ввода/вывода для Си- прог-рамм. Эти функции отражают только те операции, которые могутбыть обеспечены на большинстве современных операционных сис-тем. Процедуры достаточно эффективны для того, чтобы пользо-ватели редко чувствовали необходимость обойти их "ради -51- эффективности", как бы ни была важна конкретная задача. Инаконец, эти процедуры были задуманы авторами языка "перено-симыми" в том смысле, что они должны существовать в совмес-тимом виде на любой системе, где имеется язык Си, и чтопрограммы, которые ограничивают свои взаимодействия с сис-темными возможностями, предоставляемыми стандартной библио-текой, можно будет переносить с одной системы на другую посуществу без изменений. Далее описываются основные принципы организацииввода/вывода в программах на языке Си, использующих библио-теку ввода/вывода. Полное описание этой библиотеки имеется вруководстве программиста (часть 4) или в оперативной доку-ментации (" man (3)"). Программы, работающие в ОС ДЕМОС,могут также обращаться к функциям ввода/вывода низкогоуровня, которые реализованы непосредственно в ядре ОС ДЕМОС,но такая необходимость возникает достаточно редко.

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: