* 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)"). Программы, работающие в ОС ДЕМОС,могут также обращаться к функциям ввода/вывода низкогоуровня, которые реализованы непосредственно в ядре ОС ДЕМОС,но такая необходимость возникает достаточно редко.





