Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Керниган, Ричи Весь текст 454.51 Kb

Язык Си

Предыдущая страница Следующая страница
1 ... 31 32 33 34 35 36 37  38 39
генерируется указатель на эту функцию. Следовательно, чтобы
передать одну функцию другой, можно написать

 INT F();
 ...
 G(F);

Тогда определение функции G могло бы выглядеть так:

G(FUNCP)
INT(*FUNCP)();
\(
   ...
   (*FUNCP)();
   ...
\)

Обратите внимание, что в вызывающей процедуре функция F дол-
жна быть описана явно, потому что за ее появлением в G(F) не
следует скобка ( .

     22.3. Массивы, указатели и индексация

    Каждый раз, когда идентификатор, имеющий тип массива,
появляется в выражении, он преобразуется в указатель на пер-
вый член этого массива. Из-за этого преобразования массивы
не являются L-значениями. По определению операция индексация
[] интерпретируется таким образом, что E1[E2] считается
идентичным выражению *((е1)+(е2)). Согласно правилам преоб-
разований, применяемым при операции +, если E1 - массив, а
е2 - целое, то е1[е2] ссылается на е2-й член массива е1. По-
этому несмотря на несимметричный вид операция индексации яв-
ляется коммутативной.
    В случае многомерных массивов применяется последователь-
ное правило. Если е является N-мерным массивом размера
I*J*...*K, то при появлении в выражении е преобразуется в
указатель на (N-1)-мерный массив размера J*...*K. Если опе-
рация * либо явно, либо неявно, как результат индексации,
применяется к этому указателю, то результатом операции будет
указанный (N-1)-мерный массив, который сам немедленно преоб-
разуется в указатель.
    Рассмотрим, например, описание

INT X[3][5];

Здесь X массив целых размера 3*5. При появлении в выражении
X преобразуется в указатель на первый из трех массивов из 5
целых. В выражении X[I], которое эквивалентно *(X+I), снача-
ла X преобразуется в указатель так, как описано выше; затем
I преобразуется к типу X, что вызывает умножение I на длину
объекта, на который указывает указатель, а именно на 5 целых
объектов. Результаты складываются, и применение косвенной
адресации дает массив (из 5 целых), который в свою очередь
преобразуется в указатель на первое из этих целых. Если в
выражение входит и другой индекс, то таже самая аргументация
применяется снова; результатом на этот раз будет целое.
    Из всего этого следует, что массивы в языке "C" хранятся
построчно ( последний индекс изменяется быстрее всего) и что
первый индекс в описании помогает определить общее количест-
во памяти, требуемое для хранения массива, но не играет ни-
какой другой роли в вычислениях, связанных с индексацией.

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

    Разрешаются определенные преобразования, с использовани-
ем указателей , но они имеют некоторые зависящие от конкрет-
ной реализации аспекты. Все эти преобразования задаются с
помощью операции явного преобразования типа; см. П. 15.2 и
16.7.
    Указатель может быть преобразован в любой из целочислен-
ных типов, достаточно большой для его хранения. Требуется ли
при этом INT или LONG, зависит от конкретной машины. Преоб-
разующая функция также является машинно-зависимой, но она
будет вполне естественной для тех, кто знает структуру адре-
сации в машине. Детали для некоторых конкретных машин приво-
дятся ниже.
    Объект целочисленного типа может быть явным образом пре-
образован в указатель. такое преобразование всегда переводит
преобразованное из указателя целое в тот же самый указатель,
но в других случаях оно будет машинно-зависимым.

    Указатель на один тип может быть преобразован в указа-
тель на другой тип. Если преобразуемый указатель не указыва-
ет на объекты, которые подходящим образом выравнены в памя-
ти, то результирующий указатель может при использовании вы-
зывать ошибки адресации. Гарантируется, что указатель на
объект заданного размера может быть преобразован в указатель
на объект меньшего размера и снова обратно, не претерпев при
этом изменения.
    Например, процедура распределения памяти могла бы прини-
мать запрос на размер выделяемого объекта в байтах, а возв-
ращать указатель на символы; это можно было бы использовать
следующим образом.

 EXTERN CHAR *ALLOC();
 DOUBLE *DP;
 DP=(DOUBLE*) ALLOC(SIZEOF(DOUBLE));
 *DP=22.0/7.0;

Функция ALLOC должна обеспечивать (машинно-зависимым спосо-
бом), что возвращаемое ею значение будет подходящим для пре-
образования в указатель на DOUBLE; в таком случае использо-
вание этой функции будет переносимым.
    Представление указателя на PDP-11 соответствует 16-бито-
вому целому и измеряется в байтах. Объекты типа CHAR не име-
ют никаких ограничений на выравнивание; все остальные объек-
ты должны иметь четные адреса.
    На HONEYWELL 6000 указатель соответствует 36-битовому
целому; слову соответствует 18 левых битов и два непосредст-
венно примыкающих к ним справа бита, которые выделяют символ
в слове. Таким образом, указатели на символы измеряются в
единицах 2 в степени 16 байтов; все остальное измеряется в
единицах 2 в степени 18 машинных слов. Величины типа DOUBLE
и содержащие их агрегаты должны выравниваться по четным ад-
ресам слов (0 по модулю 2 в степени 19). Эвм IBM 370 и
INTERDATA 8/32 сходны между собой. На обеих машинах адреса
измеряются в байтах; элементарные объекты должны быть выров-
нены по границе, равной их длине, так что указатели на SHORT
должны быть кратны двум, на INT и FLOAT - четырем и на
DOUBLE - восьми. Агрегаты выравниваются по самой строгой
границе, требуемой каким-либо из их элементов.

     23. Константные выражения

    В нескольких местах в языке "C" требуются выражения, ко-
торые после вычисления становятся константами: после вариан-
тного префикса CASE, в качестве границ массивов и в инициа-
лизаторах. В первых двух случаях выражение может содержать
только целые константы, символьные константы и выражения
SIZEOF, возможно связанные либо бинарными операциями

 + - * / . % & \! Ч << >> == 1= <> <= >=

либо унарными операциями

- \^

либо тернарной операцией ?:

Круглые скобки могут использоваться для группировки, но не
для обращения к функциям.

    В случае инициализаторов допускается большая (ударение
на букву о) свобода; кроме перечисленных выше константных
выражений можно также применять унарную операцию & к внешним
или статическим объектам и к внешним или статическим масси-
вам, имеющим в качестве индексов константное выражение.
Унарная операция & может быть также применена неявно, в ре-
зультате появления неиндексированных массивов и функций. Ос-
новное правило заключается в том, что после вычисления ини-
циализатор должен становится либо константой, либо адресом
ранее описанного внешнего или статического объекта плюс или
минус константа.

     24. Соображения о переносимости

    Некоторые части языка "C" по своей сути машинно-зависи-
мы. Следующие ниже перечисление потенциальных трудностей хо-
тя и не являются всеобъемлющими, но выделяет основные из
них.
    Как показала практика, вопросы, целиком связанные с ап-
паратным оборудованием, такие как размер слова, свойства
плавающей арифметики и целого деления, не представляют осо-
бенных затруднений. Другие аспекты аппаратных средств нахо-
дят свое отражение в различных реализациях. Некоторые из
них, в частности, знаковое расширение (преобразующее отрица-
тельный символ в отрицательное целое) и порядок, в котором
помещаются байты в слове, представляют собой неприятность,
которая должна тщательно отслеживаться. Большинство из ос-
тальных проблем этого типа не вызывает сколько-нибудь значи-
тельных затруднений.
    Число переменных типа REGISTER, которое фактически может
быть помещено в регистры, меняется от машины к машине, также
как и набор допустимых для них типов. Тем не менее все ком-
пиляторы на своих машинах работают надлежащим образом; лиш-
ние или недопустимые регистровые описания игнорируются.
    Некоторые трудности возникают только при использовании
сомнительной практики программирования. Писать программы,
которые зависят от каких- либо этих свойств, является чрез-
вычайно неразумным.
    Языком не указывается порядок вычисления аргументов фун-
кций; они вычисляются справа налево на PDP-11 и VAX-11 и
слева направо на остальных машинах. порядок, в котором про-
исходят побочные эффекты, также не специфицируется.
    Так как символьные константы в действительности являются
объектами типа INT, допускается использование символьных
констант, состоящих из нескольких символов. Однако, посколь-
ку порядок, в котором символы приписываются к слову, меняет-
ся от машины к машине, конкретная реализация оказывается
весьма машинно-зависимой.
    Присваивание полей к словам и символов к целым осуществ-
ляется справо налево на PDP-11 и VAX-11 и слева направо на
других машинах. эти различия незаметны для изолированных
программ, в которых не разрешено смешивать типы (преобразуя,
например, указатель на INT в указатель на CHAR и затем про-
веряя указываемую память), но должны учитываться при согла-
совании с накладываемыми извне схемами памяти.

    Язык, принятый на различных компиляторах, отличается
только незначительными деталями. Самое заметное отличие сос-
тоит в том, что используемый в настоящее время компилятор на
PDP-11 не инициализирует структуры, которые содержат поля
битов, и не допускает некоторые операции присваивания в оп-
ределенных контекстах, связанных с использованием значения
присваивания.

     25. Анахронизмы

    Так как язык "C" является развивающимся языком, в старых
программах можно встретить некоторые устаревшие конструкции.
Хотя большинство версий компилятора поддерживает такие анах-
ронизмы, они в конце концов исчезнут, оставив за собой толь-
ко проблемы переносимости.
    В ранних версиях "C" для проблем присваивания использо-
валась форма =ON, а не ON=, приводя к двусмысленностям, ти-
пичным примером которых является

X = -1

где X фактически уменьшается, поскольку операции = и - при-
мыкают друг к другу, но что вполне могло рассматриваться и
как присваивание -1 к X.
    Синтаксис инициализаторов изменился: раньше знак равенс-
тва, с которого начинается инициализатор, отсутствовал, так
что вместо

INT X = 1;

использовалось

INT X 1;

изменение было внесено из-за инициализации

INT F (1+2)

которая достаточно сильно напоминает определение функции,
чтобы смутить компиляторы.

     26. Сводка синтаксических правил

    Эта сводка синтаксиса языка "C" предназначена скорее для
облегчения понимания и не является точной формулировкой язы-
ка.

     26.1. Выражения

    Основными выражениями являются следующие:

   выражение:
    первичное-выражение
  * выражение
  & выражение
  - выражение
  ! Выражение
 \^ выражение
 ++ L-значение
 -- L-значение
  L-значение ++
  L-значение --

  SIZEOF выражение
  (имя типа) выражение
  выражение бинарная-операция выражение
  выражение ? Выражение : выражение
  L-значение операция-присваивания выражение
  выражение , выражение
   первичное выражение:
  идентификатор
  константа
  строка
  (выражение)
  первичное-выражение (список выражений
          необ)
  первичное-выражение [выражение]
  L-значение . Идентификатор
  первичное выражение -> идентификатор
   L-значение:
  идентификатор
  первичное-выражение [выражение]
  L-значение . Идентификатор
  первичное-выражение -> идентификатор
  * выражение
  (L-значение)

Операции первичных выражений

  () []  .  ->

имеют  самый  высокий  приоритет  и  группируются   слева
направо. Унарные операции

  *  &  -  !  \^  ++  --  SIZEOF(Имя типа)

имеют более низкий приоритет, чем операции первичных выраже-
ний, но более высокий, чем приоритет любой бинарной опера-
ции. Эти операции группируются справа налево. Все бинарные
операции и условная операция (прим. Перевод.: условная опе-
рация группируется справа налево; это изменение внесено в
язык в 1978 г.) группируются слева направо и их приоритет
убывает в следующем порядке:

  Бинарные операции:
      *   /   %
      +   -
      >>  <<
      <   >  <=   >=
Предыдущая страница Следующая страница
1 ... 31 32 33 34 35 36 37  38 39
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама