Главная страница
Навигация по странице:

  • А 12.5. Условная компиляция

  • А 12.6. Нумерация строк

  • А 12.7. Генерация сообщения об ошибке

  • А 12.8. Прагма

  • А 12.9. Пустая директива Строка препроцессора вида не вызывает никаких действий. А 12.10. Заранее определенные имена

  • А 13. Грамматика

  • Язык программирования Си Брайан Керниган, Деннис Ритчи 3е издание Версия 1 Table of Contents


    Скачать 2.33 Mb.
    НазваниеЯзык программирования Си Брайан Керниган, Деннис Ритчи 3е издание Версия 1 Table of Contents
    Дата18.09.2022
    Размер2.33 Mb.
    Формат файлаpdf
    Имя файлаBrian_Kernighan_Dennis_Ritchie-The_C_Programming_Language-RU.pdf
    ТипДокументы
    #683263
    страница28 из 31
    1   ...   23   24   25   26   27   28   29   30   31

    А 12.4. Включение файла
    Управляющая строка
    # include <имя-файла> заменяется на содержимое файла с именем имя-файла. Среди символов, составляющих имя-файла, не должно быть знака
    >
    и символа новой строки. Результат не определен, если имя-файла содержит любой из символов "
    ,
    '
    ,
    \
    или пару символов
    /*
    . Порядок поиска указанного файла зависит от реализации.
    Подобным же образом выполняется управляющая строка
    # include "имя-файла"
    Сначала поиск осуществляется по тем же правилам, по каким компилятор ищет первоначальный исходный файл (механизм этого поиска зависит от реализации), а в случае неудачи осуществляется методом поиска, принятым в
    #include первого типа. Результат остается неопределенным, если имя файла содержит "
    ,
    \
    или
    /*
    ; использование знака
    >
    разрешается.
    Наконец,директива
    # include последовательность-лексем
    не совпадающая ни с одной из предыдущих форм, рассматривает последовательность лексем как текст, который в результате всех макроподстановок должен дать
    #include <...>
    или
    #include "..."
    Сгенерированная таким образом директива далее будет интерпретироваться в соответствии с полученной формой.
    Файлы, вставляемые с помощью
    #include
    , сами могут содержать в себе директивы
    #include
    А 12.5. Условная компиляция
    Части программы могут компилироваться условно, если они оформлены в соответствии со следующим схематично изображенным синтаксисом:
    условная-конструкция-препроцессора:
    if-строка текст elif-части else-часть
    необ
    #endif if-строка:
    # if константное-выражение
    # ifdef идентификатор
    # ifndef идентификатор
    elif-части:
    elif-строка текст
    elif-части
    необ
    elif-строка:
    # elif константное-выражение
    else-часть:
    else-строка текст
    else-строка:
    # else
    Каждая из директив (if-строка, elif-строка, else-строка и
    #endif
    ) записывается на отдельной строке.
    Константные выражения в
    #if и последующих строках
    #elif вычисляются по порядку, пока не обнаружится выражение с ненулевым (истинным) значением; текст, следующий за строкой с нулевым значением, выбрасывается. Текст, расположенный за директивой с ненулевым значением, обрабатывается обычным образом. Под словом "текст" здесь имеется в виду любая последовательность строк, включая строки препроцессора, которые не являются частью условной структуры; текст может быть и пустым. Если строка
    #if или
    #elif с ненулевым значением выражения найдена и ее текст обработан, то последующие строки
    #elif и
    #else вместе со своими текстами выбрасываются. Если все выражения имеют нулевые значения и присутствует строка
    #else
    , то следующий за ней текст обрабатывается обычным образом. Тексты "неактивных" ветвей условных конструкций, за исключением тех, которые заведуют вложенностью условных конструкций, игнорируются.
    Константные выражения в
    #if и
    #elif являются объектами для обычной макроподстановки. Более того, прежде чем просматривать выражения вида defined идентификатор и defined ( идентификатор)
    на предмет наличия в них макровызова, они заменяются на
    1L
    или
    0L
    в зависимости от того, был или не был определен препроцессором указанный в них идентификатор. Все идентификаторы, оставшиеся после макрорасширения, заменяются на 0L. Наконец, предполагается, что любая целая константа всегда имеет суффикс
    L
    , т. е. вся арифметика имеет дело с операндами только типа long или unsigned long
    Константное выражение (А7.19) здесь используется с ограничениями: оно должно быть целочисленным, не может содержать в себе перечислимых констант, преобразований типа и операторов sizeof.
    Управляющие строки
    #ifdef идентификатор
    #ifndef идентификатор эквивалентны соответственно строкам
    # if defined идентификатор
    # if ! defined идентификатор
    Строки
    #еlif не было в первой версии языка, хотя она и использовалась в некоторых препроцессорах. Оператор препроцессора defined
    — также новый.
    А 12.6. Нумерация строк
    Для удобства работы с другими препроцессорами, генерирующими Си-программы, можно использовать одну из следующих директив:
    # line константа "имя-файла"
    # line константа
    Эти директивы предписывают компилятору считать, что указанные десятичное целое и идентификатор являются номером следующей строки и именем текущего файла соответственно. Если имя файла отсутствует, то ранее запомненное имя не изменяется. Расширения макровызовов в директиве
    #line выполняются до интерпретации последней.
    А 12.7. Генерация сообщения об ошибке
    Строка препроцессора вида
    # error последовательность-лексем
    необ
    приказывает ему выдать диагностическое сообщение, включающее заданную последовательность лексем.
    А 12.8. Прагма
    Управляющая строка вида
    # pragma последователъностъ-лексемнеоб призывает препроцессор выполнить зависящие от реализации действия. Неопознанная прагма игнорируется.
    А 12.9. Пустая директива
    Строка препроцессора вида
    # не вызывает никаких действий.

    А 12.10. Заранее определенные имена
    Препроцессор "понимает" несколько заранее определенных идентификаторов; их он заменяет специальной информацией. Эти идентификаторы (и оператор препроцессора defined в том числе) нельзя повторно переопределять, к ним нельзя также применять директиву
    #undef
    . Это следующие идентификаторы:
    LINE
    Номер текущей строки исходного текста, десятичная константа.
    FILE
    Имя компилируемого файла, строка.
    DATE
    Дата компиляции в виде "Ммм дд гггг", строка.
    TIME
    Время компиляции в виде "чч: мм: ее", строка.
    STDC
    Константа 1. Предполагается, что этот идентификатор определен как 1 только в тех реализациях, которые следуют стандарту.
    Строки
    #error и
    #pragma впервые введены ANSI-стандартом. Заранее определенные макросы препроцессора также до сих пор не описывались, хотя и использовались в некоторых реализациях.
    А 13. Грамматика
    Ниже приведены грамматические правила, которые мы уже рассматривали в данном приложении. Они имеют то же содержание, но даны в ином порядке.
    Здесь не приводятся определения следующих символов-терминов: целая-константа, символьная-
    константа, константа-с-плавающей-точкой, идентификатор, строка и константа-перечисление. Слова, набранные обычным латинским шрифтом (не курсивом), и знаки рассматриваются как символы-термины и используются точно в том виде, как записаны. Данную грамматику можно механически трансформировать в текст, понятный системе автоматической генерации грамматического распознавателя. Для этого помимо добавления некоторых синтаксических пометок, предназначенных для указания альтернативных продукций, потребуется расшифровка конструкции со словами "один из" и дублирование каждой продукции, использующей символ с индексом необ., причем один вариант продукции должен быть написан с этим символом, а другой - без него. С одним изменением, а именно — удалением процукции typedef-имя:
    идентификатор и объявлением typedef-имени символом-термином, данная грамматика будет понятна генератору грамматического распознавателя YАСС. Ей присуще лишь одно противоречие, вызываемое неоднозначностью конструкции if
    - else
    единица-трансляции:
    внешнее-объявление
    единица-трансляции внешнее-объявление
    внешнее-объявление:
    определение-функции
    объявление
    определение-функции:
    спецификаторы-объявления
    необ
    объявитель
    список-объявлений
    необ
    составная-инструщия
    объявление:
    спецификаторы-объявления список-инициализаторов-объявителей
    необ
    список-объявлений:
    объявление
    список-объявлений объявление

    спецификаторы-объявления:
    спецификатор-класса-памяти спецификаторы-объявления
    необ
    спецификатор-типа спецификаторы-объявления
    необ
    квалификатор-типа спецификаторы-объявления
    необ
    спецификатор-класса-памяти: один из auto register static extern typedef
    спецификатор-типа: один из void char short int long float double signed unsigned
    спецификатор-структуры-или-объединения
    спецификатор-перечисления
    typedef-имя
    квалификатор-типа: один из const volatile
    спецификатор-структуры-или-объединения:
    структура-или-объединение идентификатор
    необ
    { список-объявлений-
    структуры }
    структура-или-объединение идентификатор
    структура-или-объединение: одно из struct union
    список-объявлений-структуры:
    объявление-структуры
    список-объявлений-структуры объявление-структуры
    список-объявителей-инициализаторов:
    объявитель-инициализатор
    список-объявителей-инициализаторов , объявитель-инициализатор
    объявитель-инициализатор:
    объявитель
    объявитель = инициализатор
    объявление-структуры:
    список-спецификаторов-квалификаторов список-объявителей-структуры
    список-спецификаторов-квалификаторов:
    спецификатор-типа список-спецификаторов-квалификаторов
    необ
    квалификатор-типа список-спецификаторов-квалификаторов
    необ
    список-структуры-объявителей:
    структуры-объявитель
    список-структуры-объявителей , структуры-объявителъ
    структуры-объявитель:
    объявитель
    объявитель
    необ
    : константное-выражение

    спецификатор-перечисления: enum идентификатор
    необ
    { список-перечислителей } enuь идентификатор
    список-перечислителей:
    перечислитель
    список-перечислителей перечислитель
    перечислитель:
    идентификатор
    указатель
    необ
    собственно-объявитель
    собственно-объявитель:
    идентификатор
    ( объявитель )
    собственно-объявитель [ константное-выражение
    необ
    ]
    собственно-объявитель ( список-типов-параметров )
    собственно-объявитель ( список-идентификаторов
    необ
    )
    указатель:
    * список-квалификаторов-типа
    необ
    * список-квалификаторов-типа
    необ
    указатель
    список-квалификаторов-типа:
    квалификатор-типа
    список-квалификаторов-типа квалификатор-типа
    список-типов-параметров:
    список-параметров
    список-параметров , ...
    список-параметров:
    объявление-параметра
    список-параметров , объявление-параметра
    объявление-параметра:
    спецификаторы-объявления объявитель
    спецификаторы-объявления абстрактный-объявитель
    необ
    список-идентификаторов:
    идентификатор
    список-идентификаторов , идентификатор
    инициализатор:
    выражение-присваивания
    { список-инициализаторов }
    { список-инициализаторов , }
    список-инициализаторов:
    инициализатор
    список-инициализаторов , инициализатор
    имя-типа:

    список-спецификаторов-квалификаторов абстрактный-объявитель
    необ
    абстрактный-объявитель:
    указатель
    указатель
    необ
    собственно-абстрактный-объявитель
    собственно-абстрактный-объявитель:
    ( абстрактный-объявитель )
    собственно-абстрактный-обьявитель
    необ
    [ константное-выражение
    необ
    ]
    собственно-аострактныи-объявитель
    необ
    ( список-типов-параметров
    необ
    )
    typedef-имя:
    идентификатор
    инструкция:
    помеченная-инструкция
    инструкция-выражение
    составная-инструкция
    инструкция-выбора
    циклическая-инструкция
    инструкция-перехода
    помеченная-инструкция:
    идентификатор : инструкция case константное-выражение : инструкция default : инструкция
    инструкция-выражение:
    выражение
    необ
    ;
    составная-инструкция:
    { список-объявлений
    необ
    список-инструкций
    необ
    }
    список-инструкций:
    инструкция
    список-инструкций инструкция
    инструкция-выбора: if ( выражение ) инструкция if ( выражение ) инструкция else инструкция switch ( выражение ) инструкция
    циклическая-инструкция: while ( выражение ) инструкция do инструкция while ( выражение ) for ( выражение
    необ
    ; выражение
    необ
    ; выражение
    необ
    ) инструкция
    инструкция-перехода: goto идентификатор ; continue ; break ; return выражение
    необ
    ;

    выражение:
    выражение-присваивания
    выражение , выражение-присваивания
    выражение-присваивания:
    условное-выражение
    унарное-выражение оператор-присваивания выражение-присваивания
    оператор-присваивания: один из
    *=
    /=
    %=
    +=
    -=
    <<= >>= &=
    ^=
    |=
    условное-выражение:
    логическое-ИЛИ-выражение
    логическое-ИЛИ-выражение ? выражение : условное-выражение
    константное-выражение:
    условное-выражение
    логическое-ИЛИ-выражение:
    логическое-И-выражение
    логическое-ИЛИ-выражение || логическое-И-выражение
    логическое-И-выражение:
    ИЛИ-выражение
    логическое-И-выражение && ИЛИ-выражение
    ИЛИ-выражение:
    исключающее-ИЛИ-выражение
    ИЛИ-выражение | исключающее-ИЛИ-выражение
    исключающее-ИЛИ-выражение:
    И-выражение
    исключающее-ИЛИ-выражение ^ И-выражение
    И-выражение:
    выражение-равенства
    И-выражение & выражение-равенства
    выражение-равенства:
    выражение-отношения
    выражение-равенства == выражение-отношения
    выражение-равенства != выражение-отношения
    выражение-отношения:
    сдвиговое-выражение
    выражение-отношения < сдвиговое-выражение
    выражение-отношения > сдвиговое-выражение
    выражение-отношения <= сдвиговое-выражение
    выражение-отношения >= сдвиговое-выражение
    сдвиговое-выражение:
    аддитивное-выражение
    сдвиговое-выражение >> аддитивное-выражение

    сдвиговое-выражение << аддитивное-выражение
    аддитивное-выражение:
    мультипликативное-выражение
    аддитивное-выражение + мультипликативное-выражение
    аддитивное-выражение - мультипликативное-выражение
    мультипликативное-выражение:
    выражение-приведенное-к-типу
    мультипликативное-выражение * выражение-приведенное-к-типу
    мультипликативное-выражение / выражение-приведенное-к-типу
    мулътипликативное-выражение % выражение-приведенное-к-типу
    выражение-приведенное-к-типу:
    унарное-выражение
    ( имя-типа ) выражение-приведенное-к-типу
    унарное-выражение:
    постфиксное-выражение
    ++ унарное-выражение
    -- унарное-выражение
    унарный-оператор выражение-приведенное-к-типу
    sizeof унарное-выражение sizeof ( имя-типа )
    унарный-оператор: один из
    &
    *
    +
    -


    !
    постфиксное-выражение:
    первичное-выражение
    постфиксное-выражение [ выражение ]
    постфиксное-выражение ( список-аргументов-выражений
    необ
    )
    постфиксное-выражение . идентификатор
    постфиксное-выражение -> идентификатор
    постфиксное-выражение ++
    постфиксное-выражение --
    первичное-выражение:
    идентификатор
    константа
    строка
    ( выражение )
    список-аргументов-выражений:
    выражение-присваивания
    список-аргументов-выражений , выражение-присваивания
    константа:
    целая-константа
    символьная-константа
    константа-с-плавающей-точкой
    константа-перечисление

    Ниже приводится грамматика языка препроцессора в виде перечня структур управляющих строк. Для механического получения программы грамматического разбора она не годится. Грамматика включает символ текст, который означает текст обычной программы, безусловные управляющие строки препроцессора и его законченные условные конструкции.
    управляющая-строка:
    # define идентификатор последовательность-лексем
    # define идентификатор ( идентификатор ... идентификатор )
    последовательность-лексем
    # undef идентификатор
    # include <имя-файла>
    # include "имя-файла"
    # include последовательность-лексем
    # line константа "идентификатор"
    # line константа
    # error последовательность-лексем
    необ
    # pragma последовательность-лексем
    необ
    #
    условная-конструкция-препроцессора
    условная-конструкция-препроцессора: if-строка текст elif-части else-часть
    необ
    # endif
    if-строка:
    # if константное-выражение
    # ifdef идентификатор
    # ifndef идентификатор
    elif-части:
    elif-строка текст
    elif-части
    необ
    elif-строка:
    # elif константное-выражение else-часть: else-строка текст еlsе-строка:
    # else

    1   ...   23   24   25   26   27   28   29   30   31


    написать администратору сайта