Б. Керриган, Д. Ритчи Язык программирования C. Б. Керниган, Д. зык программирования и . Издание 3е, исправленное Перевод с английского под редакцией Вс. С. Штаркмана СанктПетербург 2003
Скачать 31.48 Mb.
|
А Включение файла Управляющая строка include заменяется на содержимое файла с именем имя-файла. Среди символов, составляющих имя-файла, не должно быть знака > и символа новой стро- ки. Результат не определен, если имя-файла содержит любой из симво- \ пару Порядок поиска указанного файла зави- сит от реализации. Подобным же образом выполняется управляющая строка « include "имя-файла" Сначала поиск осуществляется по тем же правилам, по каким компиля- тор ищет первоначальный исходный файл (механизм этого поиска зави- сит от реализации), а в случае неудачи осуществляется методом поиска, принятым в первого типа. Результат остается неопределенным, если имя файла \ или использование знака > разрешается. « include последовательность-лексем не совпадающая ни с одной из предыдущих форм, рассматривает после- довательность лексем как текст, который в результате всех макроподста- новок должен дать . > или Сгенерированная таким образом директива далее будет интерпретироваться в соответствии с полученной формой. Файлы, вставляемые с помощью сами могут содержать в себе директивы А Препроцессирование А Условная компиляция Части программы могут компилироваться условно, если они оформле- ны в соответствии со следующим схематично изображенным синтакси- сом: текст if идентификатор tfifndef идентификатор текст elif-части elif константное-выражение else-часть: else-строка текст else-строка: Каждая из директив (if-строка, elif-строка, else-строка и ttendif) записы- вается на отдельной строке. Константные выражения в и последу- ющих строках flelif вычисляются по порядку, пока не обнаружится вы- ражение с ненулевым (истинным) значением; текст, следующий за стро- кой с нулевым значением, выбрасывается. Текст, расположенный за ди- рективой с ненулевым значением, обрабатывается обычным образом. Под словом "текст" здесь имеется в виду любая последовательность строк, включая строки препроцессора, которые не являются частью условной структуры; текст может быть и пустым. Если строка или с нену- левым значением выражения найдена и ее текст обработан, то последую- щие строки tfelif и flelse вместе со своими текстами выбрасываются. Если все выражения имеют нулевые значения и присутствует строка flelse, то следующий за ней текст обрабатывается обычным образом. Тексты "не- активных" ветвей условных конструкций, за исключением тех, которые заведуют вложенностью условных конструкций, игнорируются. Константные выражения в flif и являются объектами для обыч- ной макроподстановки. Более того, прежде чем просматривать выраже- ния вида defined идентификатор и ( 300 Приложение А. Справочное руководство на предмет наличия в них макровызова, они заменяются на или OL в за- висимости от был или не был определен препроцессором указанный в них идентификатор. Все идентификаторы, оставшиеся после макрорас- ширения, заменяются на Наконец, предполагается, что любая целая константа всегда имеет суффикс L, т. е. вся арифметика имеет дело с опе- рандами только типа long или unsigned long. Константное выражение здесь используется с ограничениями: оно должно быть целочисленным, не может содержать в себе перечисли- мых констант, преобразований типа и операторов Управляющие строки идентификатор идентификатор эквивалентны соответственно строкам if идентификатор if ! defined идентификатор Строки 1 f не было в первой версии языка, хотя она и использовалась в не- которых препроцессорах. Оператор препроцессора defined - также новый. А Нумерация строк Для удобства работы с другими препроцессорами, генерирующими Си- программы, можно использовать одну из следующих директив: line константа "имя файла" line константа Эти директивы предписывают компилятору считать, что указанные де- сятичное целое и идентификатор являются номером следующей строки и именем текущего файла соответственно. Если имя файла отсутствует, то ранее запомненное имя не изменяется. Расширения макровызовов в ди- рективе tfline выполняются до интерпретации последней. А Генерация сообщения об ошибке Строка препроцессора вида error приказывает ему выдать диагностическое сообщение, включающее задан- ную последовательность лексем. А 12.8. Прагма Управляющая строка вида pragma А 13. Грамматика призывает препроцессор выполнить зависящие от реализации действия. Неопознанная прагма игнорируется. А Пустая директива Строка препроцессора вида не вызывает никаких действий. А Заранее определенные имена Препроцессор "понимает" несколько заранее определенных идентифи- каторов; их он заменяет специальной информацией. Эти идентификато- ры (и оператор препроцессора в том числе) нельзя повторно пе- реопределять, к ним нельзя также применять директиву Это сле- дующие идентификаторы: LINE Номер текущей строки исходного текста, десятичная константа. Имя компилируемого файла, строка. DATE Дата компиляции виде дд строка. TIME Время компиляции в виде строка. STDC Константа что этот идентифика- тор определен как 1 только в тех реализациях, кото- рые следуют стандарту. Строки и tfpragma впервые введены Заранее опре- деленные макросы препроцессора также до сих пор не описывались, хотя и использовались в некоторых реализациях. А 13. Грамматика Ниже приведены грамматические правила, которые мы уже рассматри- вали в данном приложении. Они имеют то же содержание, но даны в ином порядке. Здесь не приводятся определения следующих символов-терминов: символъная-константа, идентификатор, строка и константа-перечисление. Слова, набранные обыч- ным латинским шрифтом (не курсивом), и знаки рассматриваются как сим- волы-термины и используются точно том виде, как записаны. Данную грам- матику можно механически трансформировать в текст, понятный системе автоматической генерации грамматического распознавателя. Для этого помимо добавления некоторых синтаксических пометок, предназначен- ных для указания альтернативных продукций, потребуется расшифровка 302 Приложение А. Справочное руководство конструкции со словами "один из" и дублирование каждой продукции, использующей символ с индексом необ., причем один вариант продукции должен быть написан с этим символом, а другой - без него. С одним измене- нием, а именно - удалением и объ- явлением символом-термином, данная грамматика будет по- нятна генератору грамматического распознавателя АСС. Ей присуще лишь одно противоречие, вызываемое неоднозначностью конструкции единица-трансляции: внешнее- объявление единица-трансляции внешнее-объявление внешнее-объявление: определение-функции объявление определение функции: спецификаторы список-объявлений объявление: список-объявлений: объявление список-объявлений объявление спецификаторы-объявления: спецификатор-класса-памяти спецификаторы-объявления из auto register static extern typedef спецификатор-типа: один из void char short int long float double signed unsigned спецификатор-пере- числения квалификатор-типа: один из const volatile структуры-или-объединения { структуры-или-объединения идентификатор А 13. Грамматика 303 одно из struct union список-объявлений-структуры: объявление-структуры список-объявлений-структуры объявление-структуры список-объявителей-инициализаторов: список-объявителей-инициализаторов , объявитель-инициализатор: объявитель = инициализатор список-объявителей- структуры список-структуры-объявителей: список-структуры-объявителей , структуры-объявитель: объявитель спецификатор-перечисления: { список-перечислителей } идентификатор список-перечислителей: перечислитель список-перечислителей перечислитель перечислитель: идентификатор собственно -объявитель: идентификатор ( 304 Приложение А. Справочное руководство собственно-объявитель [ ] собственно-объявитель собственно-объявитель ( ) указатель: * * список-типов-параметров: список-параметров список-параметров , список-параметров: объявление -параметра список-параметров , объявление-параметра объявление-параметра: спецификаторы -объявления объявитель спецификаторы-объявления список-идентификаторов: идентификатор список-идентификаторов , идентификатор инициализатор: выражение-присваивания } список-инициализаторов: инициализатор список-инициализаторов , инициализатор имя-типа: абстрактный-объявителъ: указатель ( абстрактный-объявителъ ) (список-типов-параметров А 13. Грамматика 305 идентификатор инструкция: инструкция -выражение инструкция-выбора циклическая -инструкция инструкция-перехода помеченная-инструщия: идентификатор инструкция case инструкция default : инструкция инструкция-выражение: составная-инструщия: ) список-инструкций: инструкция список-инструкций инструкция инструкция-выбора: ( выражение ) инструкция if ( выражение ) инструкция else инструкция switch ( выражение ) инструкция циклическая -инструкция: while ( выражение ) инструкция do инструкция while ( выражение ) return ; выражение: выражение-присваивания выражение , выражение-присваивания выражение -присваивания: условное -выражение унарное-выражение оператор-присваивания один из /= %= += -= 306 Приложение А. Справочное руководство логическое -ИЛИ- выражение ? выражение условное-выражение условное-выражение логическое логическое-И-выражение логическое-ИЛИ-выражение логическое-И-выражение логическое-И-выражение: ИЛИ-выражение логическое-И-выражение && ИЛИ-выражение ИЛИ-выражение: исключающее -ИЛИ-выражение ИЛИ-выражение I исключающее-ИЛИ-выражение И-выражение И-выражение: выражение-равенства И-выражение & выражение-равенства выражение-равенства: выражение-отношения выражение-отношения выражение-равенства - выражение-отношения выражение-отношения: сдвиговое -выражение выражение-отношения выражение-отношения > сдвиговое-выражение выражение-отношения <= сдвиговое-выражение выражение-отношения >= сдвиговое-выражение сдвиговое-выражение: аддитивное-выражение сдвиговое-выражение аддитивное-выражение сдвиговое-выражение аддитивное-выражение аддитивное-выражение: аддитивное-выражение + аддитивное-выражение - А 13. Грамматика 307 выражение-приведенное-к-типу * выражение- / выражение-приведенное-к-типу мулътипликативное-выражение % выражение-приведенное-к-типу выражение -приведенное -к-типу: ( имя-типа ) выражение-приведенное-к-типу унарное-выражение: ++ унарное-выражение — унарное-выражение выражение-приведенное-к-типу sizeof унарное-выражение sizeof унарный-оператор: один из постфиксное-выражение: постфиксное-выражение [ выражение ] постфиксное-выражение постфиксное-выражение . идентификатор постфиксное-выражение -> идентификатор постфиксное-выражение ++ постфиксное-выражение — первичное-выражение: идентификатор константа строка список-аргументов-выражений: выражение-присваивания , константа: целая -константа константа- -точкой константа -перечисление 308 Приложение А. Справочное руководство Ниже приводится грамматика языка препроцессора в виде перечня структур управляющих строк. Для механического получения программы грамматического разбора она не годится. Грамматика включает символ текст, который означает текст обычной программы, безусловные управ- ляющие строки препроцессора и его законченные условные конструкции. define идентификатор последовательность-лексем it идентификатор ( идентификатор идентифика- тор ) последовательность-лексем undef идентификатор ft include include "имя-файла" include последовательность-лексем line константа "идентификатор" константа последовательность -лексем текст endif идентификатор ndef идентификатор текст elif-части elif константное-выражение else-строка текст Приложение В Стандартная библиотека Настоящее приложение представляет собой краткое изложение биб- лиотеки, утвержденной в качестве ANSI-стандарта. Сама по себе библио- тека не является частью языка, однако заложенный в ней набор функций, а также определений типов и макросов составляет системную среду, под- держивающую стандарт Си. Мы не приводим здесь несколько функций с ограниченной областью применения - те, которые легко синтезируют- ся из других функций, а также опускаем все то, что касается многобайто- вых символов и специфики, обусловленной языком, национальными осо- бенностями и культурой. Функции, типы и макросы объявляются в следующих стандартных заголовочных файлах: Доступ к заголовочному файлу осуществляется с помощью строки пре- процессора Заголовочные файлы можно включать в любом порядке и сколько угод- но раз. Строка не должна быть внутри внешнего объявления или определения и должна встретиться раньше, чем что-нибудь из включае- мого заголовочного файла будет востребовано. В конкретной реализации заголовочный файл может и не быть исходным файлом. Внешние идентификаторы, начинающиеся со знака подчеркивания, а также все другие идентификаторы, начинающиеся с двух знаков под- черкивания или с подчеркивания и заглавной буквы, зарезервированы для использования в библиотеке. 310 Приложение В. Стандартная библиотека В 1. Ввод-вывод: Определенные h> функции ввода-вывода, а также типы и мак- росы составляют приблизительно одну треть библиотеки. Поток - это источник или получатель данных; его можно связать с дис- ком или с каким-то другим внешним устройством. Библиотека под- держивает два вида потоков: текстовый и бинарный, хотя на некоторых системах, в частности в они не различаются. Текстовый поток - это последовательность строк; каждая строка имеет нуль или более сим- волов и заканчивается символом ' Операционная среда может потребо- вать коррекции текстового потока (например перевода ' в символы возврат-каретки и перевод-строки). Бинарный поток - это последовательность непреобразованных байтов, представляющих собой некоторые промежуточные данные, которые обла- дают тем свойством, что если их записать, а затем прочесть той же систе- мой ввода-вывода, то мы получим информацию, совпадающую с исходной. Поток соединяется с файлом или устройством посредством его откры- тия, указанная связь разрывается путем закрытия потока. Открытие файла возвращает указатель на объект типа который содержит всю информацию, необходимую для управления этим потоком. Если не воз- никает двусмысленности, мы будем пользоваться терминами "файловый указатель" и "поток" как равнозначными. Когда программа начинает работу, уже открыты три потока: stdout В Операции над файлами Ниже перечислены функции, оперирующие с файлами. Тип size_t - беззнаковый целочисленный тип, используемый для описания результа- та оператора FILE *fopen(const char *filename, const char *mode) открывает файл с заданным именем и возвращает поток или NULL, если попытка открытия оказалась неудачной. Режим mode допускает следующие значения: - текстовый файл открывается для чтения (от - читать); - текстовый файл создается для записи; старое содержимое (если оно было) выбрасывается (от write (англ.) - писать); "а" - текстовый файл открывается или создается для записи в конец файла (от append (англ.) - добавлять); - текстовый файл открывается для исправления (т. е. для чте- ния и для записи); - текстовый файл создается для исправления; старое содержи- мое (если оно было) выбрасывается; В Ввод-вывод: - текстовый файл открывается или создается для исправления уже существующей информации и добавления новой в конец файла. Режим "исправления" позволяет читать и писать в один и тот же файл; при переходах от операций чтения к операциям записи и обратно должны осуще- ствляться обращения к или к функции позиционирования файла. Если указатель режима дополнить буквой b (например или то это будет означать, что файл бинарный. Ограничение на длину имени файла задано кон- стантой Константа FOPEN_MAX ограничивает число одновременно открытых файлов. FILE char const char FILE f reopen открывает файл с указанным режимом и связывает его с потоком st ream. Она возвращает st ream или, в случае ошибки, NULL. Обычно f reopen использует- ся для замены файлов, связанных с stdin, или r, другими файлами. int fflush(FILE Применяемая к потоку вывода функция f f l u s h производит дозапись всех ос- тавшихся в буфере (еще не записанных) данных; для потока ввода эта функ- ция не определена. Возвращает EOF в случае возникшей при записи ошибки или нуль в противном случае. Обращение вида выполняет ука- занные операции для всех потоков вывода. int fclose(FILE f lose производит дозапись еще не записанных буферизованных данных, сбра- сывает несчитанный буферизованный ввод, освобождает все автоматически запрошенные буфера, после чего закрывает поток. Возвращает EOF в случае ошибки и нуль в случае. int char remove удаляет файл с указанным именем; последующая попытка открыть файл с этим именем вызовет ошибку. Возвращает ненулевое значение в случае не- удачной попытки. int char const char rename заменяет имя файла; возвращает ненулевое значение в случае, если по- пытка изменить имя оказалась неудачной. Первый параметр задает старое имя, второй - новое. FILE создает временный файл с режимом доступа который чески удаляется при его закрытии или обычном завершении программой сво- ей работы. Эта функция возвращает поток или, если не смогла создать файл, NULL. char создает строку, не совпадающую ни с одним из имен существу- ющих файлов, и возвращает указатель на внутренний статический массив. |