рефераты

рефераты

 
 
рефераты рефераты

Меню

Реферат: Язык С рефераты

жаемой строки обратную косую черту \ .

    

·     218 -

    

Описываемая возможность особенно полезна для определения

“объявляемых констант”, как, например,

#DEFINE TABSIZE 100

INT TABLE[TABSIZE];

 

Управляющая строка вида

#UNDEF идентификатор

приводит к отмене препроцессорного определения данного иден-

тификатора.

20.2. Включение файлов

Строка управления компилятором вида

#INCLUDE “FILENAME”

приводит к замене этой строки на все содержимое файла с име-

нем FILENAME. Файл с этим именем сначала ищется в справочни-

ке начального исходного файла, а затем в последовательности

стандартных мест. В отличие от этого управляющая строка вида

 

#INCLUDE <FILENAME>

ищет файл только в стандартных местах и не просматривает

справочник исходного файла.

Строки #INCLUDE могут быть вложенными.

20.3. Условная компиляция

Строка управления компилятором вида

#IF константное выражение

проверяет, отлично ли от нуля значение константного выраже-

ния (см. П. 15). Управляющая строка вида

 

#IF DEF идентификатор

проверяет, определен ли этот идентификатор в настоящий мо-

мент в препроцессоре, т.е. Определен ли этот идентификатор с

помощью управляющей строки #DEFINE.

21. Неявные описания

Не всегда является необходимым специфицировать и класс

памяти и тип идентификатора в описании. Во внешних определе-

ниях и описаниях формальных параметров и членов структур

класс памяти определяется по контексту. Если в находящемся

внутри функции описании не указан тип, а только класс памя-

ти, то предполагается, что идентификатор имеет тип INT; если

не указан класс памяти, а только тип, то идентификатор пред-

полагается описанным как AUTO. Исключение из последнего пра-

вила дается для функций, потому что спецификатор AUTO для

функций является бессмысленным (язык “C” не в состоянии ком-

пилировать программу в стек); если идентификатор имеет тип

“функция, возвращающая ...”, то он предполагается неявно

описанным как EXTERN.

    

·     219 -

    

Входящий в выражение и неописанный ранее идентификатор,

за которым следует скобка ( , считается описанным по контек-

сту как “функция, возвращающая INT”.

22. Снова о типах

В этом разделе обобщаются сведения об операциях, которые

можно применять только к объектам определенных типов.

22.1. Структуры и объединения

Только две вещи можно сделать со структурой или объеди-

нением: назвать один из их членов (с помощью операции) или

извлечь их адрес ( с помощью унарной операции &). Другие

операции, такие как присваивание им или из них и передача их

в качестве параметров, приводят к сообщению об ошибке. В бу-

дущем ожидается, что эти операции, но не обязательно ка-

кие-либо другие, будут разрешены.

В п. 15.1 Говорится, что при прямой или косвенной ссылке

на структуру (с помощью . Или ->) имя справа должно быть

членом структуры, названной или указанной выражением слева.

Это ограничение не навязывается строго компилятором, чтобы

дать возможность обойти правила типов. В действительности

перед '.' допускается любое L-значение и затем предполагает-

ся, что это L-значение имеет форму структуры, для которой

стоящее справа имя является членом. Таким же образом, от вы-

ражения, стоящего перед '->', требуется только быть указате-

лем или целым. В случае указателя предполагается, что он

указывает на структуру, для которой стоящее справа имя явля-

ется членом. В случае целого оно рассматривается как абсо-

лютный адрес соответствующей структуры, заданный в единицах

машинной памяти.

Такие структуры не являются переносимыми.

22.2. Функции

Только две вещи можно сделать с функцией: вызвать ее или

извлечь ее адрес. Если имя функции входит в выражение не в

позиции имени функции, соответствующей обращению к ней, то

генерируется указатель на эту функцию. Следовательно, чтобы

передать одну функцию другой, можно написать

 

INT F();

  ...

G(F);

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

G(FUNCP)

INT(*FUNCP)();

 \(

    ...

(*FUNCP)();

    ...

 \)

 

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

жна быть описана явно, потому что за ее появлением в G(F) не

следует скобка ( .

    

·     220 -

    

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, зависит от конкретной машины. Преоб-

разующая функция также является машинно-зависимой, но она

будет вполне естественной для тех, кто знает структуру адре-

сации в машине. Детали для некоторых конкретных машин приво-

дятся ниже.

Объект целочисленного типа может быть явным образом пре-

образован в указатель. такое преобразование всегда переводит

преобразованное из указателя целое в тот же самый указатель,

но в других случаях оно будет машинно-зависимым.

    

·     221 -

    

Указатель на один тип может быть преобразован в указа-

тель на другой тип. Если преобразуемый указатель не указыва-

ет на объекты, которые подходящим образом выравнены в памя-

ти, то результирующий указатель может при использовании вы-

зывать ошибки адресации. Гарантируется, что указатель на

объект заданного размера может быть преобразован в указатель

на объект меньшего размера и снова обратно, не претерпев при

этом изменения.

Например, процедура распределения памяти могла бы прини-

мать запрос на размер выделяемого объекта в байтах, а возв-

ращать указатель на символы; это можно было бы использовать

следующим образом.

 

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= <> <= >=

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

 - \^

 

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

·                 
222 -

    

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

для обращения к функциям.

 

В случае инициализаторов допускается большая (ударение

на букву о) свобода; кроме перечисленных выше константных

выражений можно также применять унарную операцию & к внешним

или статическим объектам и к внешним или статическим масси-

вам, имеющим в качестве индексов константное выражение.

Унарная операция & может быть также применена неявно, в ре-

зультате появления неиндексированных массивов и функций. Ос-

новное правило заключается в том, что после вычисления ини-

циализатор должен становится либо константой, либо адресом

ранее описанного внешнего или статического объекта плюс или

минус константа.

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

Некоторые части языка “C” по своей сути машинно-зависи-

мы. Следующие ниже перечисление потенциальных трудностей хо-

тя и не являются всеобъемлющими, но выделяет основные из

них.

Как показала практика, вопросы, целиком связанные с ап-

паратным оборудованием, такие как размер слова, свойства

плавающей арифметики и целого деления, не представляют осо-

бенных затруднений. Другие аспекты аппаратных средств нахо-

дят свое отражение в различных реализациях. Некоторые из

них, в частности, знаковое расширение (преобразующее отрица-

тельный символ в отрицательное целое) и порядок, в котором

помещаются байты в слове, представляют собой неприятность,

которая должна тщательно отслеживаться. Большинство из ос-

тальных проблем этого типа не вызывает сколько-нибудь значи-

тельных затруднений.

Число переменных типа REGISTER, которое фактически может

быть помещено в регистры, меняется от машины к машине, также

как и набор допустимых для них типов. Тем не менее все ком-

пиляторы на своих машинах работают надлежащим образом; лиш-

ние или недопустимые регистровые описания игнорируются.

Некоторые трудности возникают только при использовании

сомнительной практики программирования. Писать программы,

которые зависят от каких- либо этих свойств, является чрез-

вычайно неразумным.

Языком не указывается порядок вычисления аргументов фун-

кций; они вычисляются справа налево на PDP-11 и VAX-11 и

слева направо на остальных машинах. порядок, в котором про-

исходят побочные эффекты, также не специфицируется.

Так как символьные константы в действительности являются

объектами типа INT, допускается использование символьных

констант, состоящих из нескольких символов. Однако, посколь-

ку порядок, в котором символы приписываются к слову, меняет-

ся от машины к машине, конкретная реализация оказывается

весьма машинно-зависимой.

Присваивание полей к словам и символов к целым осуществ-

ляется справо налево на PDP-11 и VAX-11 и слева направо на

других машинах. эти различия незаметны для изолированных

программ, в которых не разрешено смешивать типы (преобразуя,

например, указатель на INT в указатель на CHAR и затем про-

веряя указываемую память), но должны учитываться при согла-

совании с накладываемыми извне схемами памяти.

    

·     223 -

    

Язык, принятый на различных компиляторах, отличается

только незначительными деталями. Самое заметное отличие сос-

тоит в том, что используемый в настоящее время компилятор на

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-значение—

    

·     224 -

    

SIZEOF выражение

(имя типа) выражение

выражение бинарная-операция выражение

выражение ? Выражение : выражение

L-значение операция-присваивания выражение

выражение , выражение

первичное выражение:

идентификатор

константа

строка

(выражение)

первичное-выражение (список выражений

необ)

первичное-выражение [выражение]

L-значение . Идентификатор

первичное выражение -> идентификатор

L-значение:

идентификатор

первичное-выражение [выражение]

L-значение . Идентификатор

первичное-выражение -> идентификатор

·     выражение

(L-значение)

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

   () []  .  ->

 

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

направо. Унарные операции

    

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

 

имеют более низкий приоритет, чем операции первичных выраже-

ний, но более высокий, чем приоритет любой бинарной опера-

ции. Эти операции группируются справа налево. Все бинарные

операции и условная операция (прим. Перевод.: условная опе-

рация группируется справа налево; это изменение внесено в

язык в 1978 г.) группируются слева направо и их приоритет

убывает в следующем порядке:

 

Бинарные операции:

       *   /   %

       +   -

       >>  <<

       <   >  <=   >=

       ==  !=

       &

       \^

       \!

       &&

     \!\!

       ?:

           

·     225 -

    

Все операции присваивания имеют одинаковый приоритет и груп-

пируются справа налево.

Операции присваивания:

   =  +=  -=  *=  ?=  %=  >>=  <<=  &=  \^=  \!=

 

Операция запятая имеет самый низкий приоритет и группируется

слева направо.

26.2. Описания Описание:

спецификаторы-описания список-инициализируемых-описателей

необ;

 

спецификаторы-описания:

спецификатор-типа спецификаторы-описания

необ

спецификатор-класса-памяти спецификаторы-описания

необ

спецификатор-класса-памяти:

AUTO

STATIC

EXTERN

REGISTER

TYPEDEF

спецификатор-типа:

CHAR

SHORT

INT

LONG

UNSIGNED

FLOAT

DOUBLE

спецификатор-структуры-или-объединения

определяющее-тип-имя

список-инициализируемых-описателей:

инициализируемый-описатель

инициализируемый-описатель,

список-инициализируемых-описателей

инициализируемый-описатель

описатель-инициализатор

необ

описатель:

идентификатор

(описатель)

·     описатель описатель () описатель [константное выражение

необ]

·          
226 -

    

спецификатор-структуры-или-объединения:

STRUCT список-описателей-структуры

STRUCT идентификатор \(список-описаний-структуры\)

STRUCT идентификатор

UNION \(список-описаний-структуры\)

UNION идентификатор \(список-описаний-структуры\)

UNION идентификатор

список-описаний-структцры:

описание-структуры

описание-структуры список-описаний-структуры

описание структуры:

спецификатор-типа список-описателей-структуры:

список-описателей-структуры

описатель-структуры

описатель-структуры,список-описателей-структуры

описатель-структуры:

описатель

описатель: константное выражение

:константное-выражение

инициализатор:

= выражение

= \(список-инициализатора\)

= \(список-инициализатора\)

список инициализатора:

выражение

список-инициализатора,список-инициализатора

\(список-инициализатора\)

имя-типа:

спецификатор-типа абстрактный-описатель

абстрактный-описатель:

пусто

\(абстрактный-описатель\)

·     абстрактный-описатель абстрактный-описатель () абстрактный-описатель [константное-выражение

необ]

определяющее-тип-имя:

идентификатор

26.3. Операторы

составной-оператор:

   \(список-описаний      список-операторов

         необ      необ\)

список-описаний:

описание

описание список-описаний

список-операторов:

оператор

оператор список-операторов

оператор:

составной оператор

выражение;

    

·     227 -

    

IF (выражение) оператор

IF (выражение) оператор ELSE оператор

WHILE (выражение) оператор

DO оператор WHILE (выражение);

   FOR(выражение-1    ;выражение-2    ;выражение-3    )

       необ      необ   необ

оператор

SWITCH (выражение) оператор

CASE константное-выражение : оператор

DEFAULT: оператор

BREAK;

CONTINUE;

RETURN;

RETURN выражение;

GOTO идентификатор;

идентификатор : оператор

   ;

26.4. Внешние определения Программа:

внешнее-определение

внешнее-определение программа

внешнее-определение:

определение-функции

определение-данных

определение-функции:

спецификатор-типа     описатель-функции тело-функции

необ

описатель-функции:

описатель (список-параметров    )

необ

список-параметров:

идетификатор

идентификатор , список-параметров

тело-функции:

список-описаний-типа оператор-функции

оператор-функции:

\(список описаний     список-операторов\)

необ

определение данных:

    EXTERN  спецификатор типа    список

    необ   необ

   инициализируемых описателей    ;

необ

    STATIC  спецификатор типа     список

    необ   необ

инициализируемых описателей

необ;

26.5.          Препроцессор #DEFINE идентификатор строка-лексем #DEFINE

    

·     229 -

    

#DEFINE идентификатор(идентификатор,...,идентификатор)стр

#UNDEF идентификатор

#INCLUDE “имя-файла”

#INCLUDE <имя-файла>

#IF константное-выражение

#IFDEF идентификатор

#IFNDEF идентификатор

#ELSE

#ENDIF

#LINE константа идентификатор

 

Последние изменения языка “C” (15 ноября 1978 г.)

27. Присваивание структуры

Структуры могут быть присвоены, переданы функциям в ка-

честве аргументов и возвращены функциям. Типы участвующих

операндов должны оставаться теми же самыми. Другие правдопо-

добные операторы, такие как сравнение на равенство, не были

реализованы.

В реализации возвращения структур функциями на PDP-11

имеется коварный дефект: если во время возврата происходит

прерывание и та же самая функция пеентерабельно вызывается

во время этого прерывания, то значение возвращаемое из пер-

вого вызова, может быть испорчено. Эта трудность может воз-

никнуть только при наличии истинного прерывания, как из опе-

рационной системы, так и из программы пользователя, прерыва-

ния, которое существенно для использования сигналов; обычные

рекурсивные вызовы совершенно безопасны.

28. Тип перечисления

Введен новый тип данных,аналогичный скалярным типам язы-

ка паскаль. К спецификатору-типа в его синтаксическом описа-

нии в разделе 8.2. Приложения а следует добавить

 

спецификатор-перечисления

 

с синтаксисом

 

пецификатор-перечисления:

ENUM список-перечисления

ENUM идентификатор  список-перечисления

      -------------  -------------------

ENUM идентификатор

           

·     230 -

 

cписок-перечисления:

перечисляемое

список-перечисления, перечисляемое

 -------------------  -------------

перечисляемое:

идентификатор

идентификатор = константное выражение

  -------------   ---------------------

 

Роль идентификатора в спецификаторе-перечисления пол-

ностью аналогична роли ярлыка структуры в спецификато-

ре-структуры; идентификатор обозначает определенное перечис-

ление. Например, описание

 

ENUM COLOR \(RED, WHITE, BLACK, BLUE \);

  . . .

ENUM COLOR *CP, COL;

 

Объявляет идентификатор COLOR ярлыком перечисления типа,

описывающего различные цвета и затем объявляет CP указателем

на объект этого типа, а COL - объектом этого типа.

Идентификаторы в списке-перечисления описываются как

константы и могут появиться там, где требуются (по контекс-

ту) константы. Если не используется вторая форма перечисляе-

мого (с равеством =), то величины констант начинаются с 0 и

возрастают на 1 в соответствии с прочтением их описания сле-

ва на право. Перечисляемое с присвоением = придает соответс-

твующему идентификатору указанную величину; последующие

идентификаторы продолжают прогрессию от приписанной величи-

ны.

Все ярлыки перечисления и константы могут быть различны-

ми и непохожими на ярлыки и члены структур даже при условии

использования одного и того же множества идентификаторов.

Объекты данного типа перечисления рассматриваются как

объекты, имеющие тип, отличный от любых типов и контролирую-

щая программа LINT сообщает об ошибках несоответствия типов.

В реализации на PDP-11 со всеми перечисляемыми переменными

оперируют так, как если бы они имели тип INT.

29. Таблица изображений непечатных символов языка “C”.

В данной таблице приведены изображения некоторых симво-

лов (фигурные скобки и т.д.) языка “C”, которых может не

оказаться в знаковом наборе дисплея или печатающего устройс-

тва.

    

·     231 -

    

 !    Значение          !   Изображение   **     !

 !                      !    В тексте            !

 !  Фигурная открывающаяся  !                    !

 !    Скобка                !        \(          !

 !                          !                    !

 !  Фигурная закрывающаяся  !                    !

 !    Скобка                !        \)          !

 !                          !                    !

 ! Вертикальная             !                    !

 !    Черта                 !        \!          !

 !                          !                    !

 !                          !                    !

 !   Апостороф              !        \'          !

 !                          !                    !

 !    Волнистая             !                    !

 !      Черта               !        \^          !

 !                          !                    !

 

** П_р_и_м_е_ч_а_н_и_е:

Изображения приведены для операционой системы UNIX. При

работе компилятора “C” под управлением любой другой операци-

онной системы, необходимо воспользоваться соответствующим

руководством для данной системы.


Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28