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

  • В 8. Дальние переходы

  • В 9. Сигналы

  • В 10. Функции даты и времени

  • В 11. Зависящие от реализации пределы: и

  • C. Перечень изменений

  • Язык программирования Си Брайан Керниган, Деннис Ритчи 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
    страница31 из 31
    1   ...   23   24   25   26   27   28   29   30   31
    В 7. Списки аргументов переменной длины:
    Заголовочный файл

    предоставляет средства для перебора аргументов функции, количество и типы которых заранее не известны.
    Пусть посларг — последний именованный параметр функции f
    с переменным числом аргументов. Внутри f
    объявляется переменная ар типа va_list
    , предназначенная для хранения указателя на очередной аргумент: va_list ар;

    Прежде чем будет возможен доступ к безымянным аргументам, необходимо один раз инициализировать ар
    , обратившись к макросу va_start
    : va_start(va_list ар, посларг);
    С этого момента каждое обращение к макросу:
    тип va_arg(va_list ар, тип); будет давать значение очередного безымянного аргумента указанного типа, и каждое такое обращение будет вызывать автоматическое приращение указателя ар
    , чтобы последний указывал на следующий аргумент.
    Один раз после перебора аргументов, но до выхода из f
    необходимо обратиться к макросу void va_end(va_list ар);
    В 8. Дальние переходы:
    Объявления в

    предоставляют способ отклониться от обычной последовательности "вызов — возврат"; типичная ситуация — необходимость вернуться из "глубоко вложенного" вызова функции на верхний уровень, минуя промежуточные возвраты. int setjmp(jmp_buf env)
    Макрос setjmp сохраняет текущую информацию о вызовах в env для последующего ее использования в longjmp
    . Возвращает нуль, если возврат осуществляется непосредственно из setjmp
    , и не нуль, если — от последующего вызова longjmp
    . Обращение к setjmp возможно только в определенных контекстах; в основном это проверки в if
    , switch и циклах, причем только в простых выражениях отношения. if (setjmp() == 0)
    /* после прямого возврата */ else
    /* после возврата из longjmp */ void longjmp(jmp_buf env, int val) longjmp восстанавливает информацию, сохраненную в самом последнем вызове setjmp
    , по информации из env
    ; выполнение программы возобновляется, как если бы функция setjmp только что отработала и вернула ненулевое значение val
    . Результат будет непредсказуемым, если в момент обращения к longjmp функция, содержащая вызов setjmp
    , уже "отработала" и осуществила возврат. Доступные ей объекты имеют те значения, которые они имели в момент обращения к longjmp
    ; setjmp не сохраняет значений.
    В 9. Сигналы:
    Заголовочный файл

    предоставляет средства для обработки исключительных ситуаций, возникающих во время выполнения программы, таких как прерывание, вызванное внешним источником или ошибкой в вычислениях. void (*signal(int sig, void (*handler)(int)))(int) signal устанавливает, как будут обрабатываться последующие сигналы. Если параметр handler имеет значение
    SIG_DFL
    , то используется зависимая от реализации "обработка по умолчанию"; если значение handler равно
    SIG_IGN
    , то сигнал игнорируется; в остальных случаях будет выполнено обращение к функции, на которую указывает handler с типом сигнала в качестве аргумента. В число допустимых видов сигналов входят:

    SIGABRT
    — аварийное завершение, например от abort;
    SIGFPE
    — арифметическая ошибка: деление на 0 или переполнение;
    SIGILL
    — неверный код функции (недопустимая команда);
    SIGINT
    — запрос на взаимодействие, например прерывание;
    SIGSEGV
    — неверный доступ к памяти, например выход за границы;
    SIGTERM
    — требование завершения, посланное в программу. signal возвращает предыдущее значение handler в случае специфицированного сигнала, или
    SIGERR
    в случае возникновения ошибки.
    Когда в дальнейшем появляется сигнал sig
    , сначала восстанавливается готовность поведения "по умолчанию", после чего вызывается функция, заданная в параметре handler
    , т.е. как бы выполняется вызов
    (*handler) (sig)
    . Если функция handler вернет управление назад, то вычисления возобновятся с того места, где застал программу пришедший сигнал.
    Начальное состояние сигналов зависит от реализации. int raise(int sig) raise посылает в программу сигнал sig
    . В случае неудачи возвращает ненулевое значение.
    В 10. Функции даты и времени:
    Заголовочный файл

    объявляет типы и функции, связанные с датой и временем. Некоторые функции имеют дело с местным временем, которое может отличаться от календарного, например, в связи с зонированием времени. Типы clock_t и time_t
    — арифметические типы для представления времени, a struct tm содержит компоненты календарного времени: int tm_sec;
    — секунды от начала минуты (0,61); int tm_min;
    — минуты от начала часа (0,59); int tm_hour;
    — часы от полуночи (0,23); int tmjnday;
    — число месяца (1,31); int tmjnon;
    — месяцы с января (0,11); int tm_year;
    — годы с 1900; int tm_wday;
    —дни с воскресенья (0,6); int tm_yday;
    — дни с 1 января (0,365); int tm_isdst;
    — признак летнего времени.
    Значение tm_isdst
    — положительное, если время приходится на сезон, когда время суток сдвинуто на 1 час вперед, нуль в противном случае и отрицательное, если информация не доступна. clock_t clock(void)
    clock возвращает время, фиксируемое процессором от начала выполнения программы, или -1, если оно не известно. Для выражения этого времени в секундах применяется формула clock()/CLOCKS_PER_SEC
    time_t time(time_t *tp) time возвращает текущее календарное время
    16
    или -1, если время не известно. Если tp не равно
    NULL
    , то возвращаемое значение записывается и в
    *tp double difftime(time_t time2, time_t timel) difftime возвращает разность time2-time1
    , выраженную в секундах. time_t mktime(struct tm «tp) mktime преобразует местное время, заданное структурой
    *tp
    , в календарное, выдавая его в том же виде, что и функция time
    . Компоненты будут иметь значения в указанных диапазонах. Функция mktime возвращает календарное время или -1, если оно не представимо.
    Следующие четыре функции возвращают указатели на статические объекты, каждый из которых может быть изменен другими вызовами. char *asctime(const struct tь *tp) asctime переводит время в структуре
    *tp в строку вида
    Sun Jan 3 15:14:13 1988\n\0 char *ctime(const time_t *tp) сtime переводит календарное время в местное, что эквивалентно выполнению asctime(localtime(tp))
    struct tm *gmtime(const time_t *tp) gmtime переводит календарное время во Всемирное координированное время (Coordinated Universal
    Time — UTC). Выдает
    NULL
    , если UTC не известно. Имя этой функции, gmtime
    , происходит от
    Greenwich Mean Time (среднее время по Гринвичскому меридиану). struct tm *localtime(const time_t *tp) localtime переводит календарное время
    *tp в местное. size_t strftime(char *s, size_t smax, const char *fmt, const struct tm *tp) strftime форматирует информацию о дате и времени из
    *tp в строку s
    согласно формату fmt
    , который имеет много общих черт с форматом, задаваемым в функции printf
    . Обычные символы
    (включая и завершающий символ '\0'
    ) копируются в s
    . Каждая пара, состоящая из
    %
    и буквы, заменяется, как показано ниже, с использованием значений по форме, соответствующей местным традициям. В s
    размещается не более smax символов, strftime возвращает число символов без учета '\0'
    или нуль, если число сгенерированных символов больше smax
    %а сокращенное название дня недели
    %А полное название дня недели
    16
    Время, прошедшее после определенной даты, — обычно после 0 ч 00 мин 00 с GMT 1-го января 1970 г. — Примеч. ред.

    %b сокращенное название месяца
    %В полное название месяца.
    %с местное представление даты и времени
    %d день месяца (01-31)
    %Н час (24-часовое время) (00-23)
    %I час (12-часовое время) (01-12)
    %j день от начала года (001-366)
    %m месяц (01-12)
    %М минута (00-59)
    %р местное представление AM или РМ (до или после полудня)
    %S секунда (00-61)
    %U неделя от начала года (считая, что воскресенье - 1-й день недели) (00-53)
    %w день недели (0-6, номер воскресенья - 0)
    %W неделя от начала года (считая, что понедельник - 1 -и день недели) (00-53)
    %х местное представление даты
    %Х местное представление времени
    %y год без указания века (00-99)
    %Y год с указанием века
    %Z название временной зоны, если она есть
    %%
    %
    В 11. Зависящие от реализации пределы: и
    Заголовочный файл

    определяет константы для размеров целочисленных типов. Ниже перечислены минимальные приемлемые величины, но в конкретных реализациях могут использоваться и большие значения.
    CHAR_BIT
    8 битов в значении char
    SCHAR_MAX
    UCHAR_MAX или SCHAR_MAX максимальное значение char
    CHAR_MIN
    0 или SCHAR_MIN минимальное значение char
    INT_MAX
    +32767 максимальное значение int

    INT_MIN
    -32767 минимальное значение int
    LONG_MAX
    +2147463647 максимальное значение long
    LONG_MIN
    -2147483647 минимальное значение long
    SCHAR_MAX
    +127 максимальное значение signed char
    SCHAR_MIN
    -127 минимальное значение signed char
    SHRT_MAX
    +32767 максимальное значение short
    SHRT_MIN
    -32767 минимальное значение short
    UCHAR_MAX
    255 максимальное значение unsigned char
    UINT_MAX
    65535 максимальное значение unsigned int
    ULONG_MAX
    4294967295 максимальное значение unsigned long
    USHRT_MAX
    65535 максимальное значение unsigned short
    Имена, приведенные в следующей таблице, взяты из

    и являются константами, имеющими отношение к арифметике с плавающей точкой. Значения (если они есть) представляют собой минимальные значения для соответствующих величин. В каждой реализации устанавливаются свои значения.
    FLT_RADIX
    2 основание для представления порядка, например: 2, 16
    FLT_ROUNDS способ округления при сложении чисел с плавающей точкой
    FLT_DIG
    6
    FLT_EPSILON
    1E-5 минимальное х, такое, что 1.0 + х

    1.0
    FLT_MANT_DIG количество цифр по основанию
    FLT_RADIX
    в мантиссе
    FLT_MAX
    1E+37 максимальное число с плавающей точкой
    FLT_MAX_EXP максимальное n, такое, что
    FLT_RADIX
    n
    -1 представимо
    FLT_MIN
    1E-37 минимальное нормализованное число с плавающей точкой
    FLT_MIN_EXP минимальное n, такое, что
    10
    n представимо в виде нормализованного числа
    DBL_DIG
    10 количество верных десятичных цифр для типа double
    DBL_EPSILON
    1E-9 минимальное х, такое, что 1.0 + х

    1.0, где х принадлежит типу double
    DBL_MANT DIG количество цифр по основанию
    FLT_RADIX
    в мантиссе для чисел типа double
    DBL_MAX
    1E+37 максимальное число с плавающей точкой типа double
    DBL_MAX_EXP максимальное n, такое, что
    FLT_RADIX
    n
    -1 представимо в виде числа типа double

    DBL_MIN
    1E-37 минимальное нормализованное число с плавающей точкой типа double
    DBL_MIN_EXP минимальное n, такое, что
    10
    n представимо в виде нормализованного числа типа double

    C. Перечень изменений
    С момента публикации первого издания этой книги определение языка Си претерпело изменения. Почти все нововведения — это расширения исходной версии языка, выполненные так, чтобы сохранилась совместимость с существующими программами; некоторые изменения касаются устранения двусмысленностей первоначального описания, а некоторые представляют собой модификации, привнесенные существующей практикой. Многие из новых возможностей, впоследствии принятые другими разработчиками Си-компиляторов, были первоначально объявлены в документах, прилагаемых к компиляторам. Комитет ANSI, подготавливая стандарт языка, включил большинство этих изменений, а также ввел другие значительные модификации. Некоторые коммерческие компиляторы реализовали их еще до выпуска официального Си-стандарта.
    В этом приложении сведены воедино различия между языком, определенным в первой его редакции, и той его версии, которая принята в качестве стандарта. Здесь рассматривается только сам язык; вопросы, относящиеся к его окружению и библиотеке, не затрагиваются. Хотя последние и являются важной частью стандарта, но, поскольку в первом издании не делалось попытки описать среду и библиотеку, с соответствующими стандартными элементами сравнивать практически нечего.
     В стандарте более тщательно, по сравнению с первым изданием, определено и расширено препроцессирование: в его основу явно положены лексемы; введены новые операторы для "склеивания" лексем (
    ##
    ) и создания символьных строк (
    #
    ), а также новые управляющие строки, такие как
    #elif и
    #pragma
    ; разрешено повторное определение макроса с той же последовательностью лексем; отменена подстановка параметров внутри строк. Разрешено "склеивание" строк с помощью знака
    \
    в любом месте, не только в строках и макроопределениях (см. А12).
     Минимальное число значимых символов всех внутренних идентификаторов доведено до 31; для идентификаторов с внешней связью оно остается равным 6; буквы нижнего и верхнего регистров не различаются. (Многие реализации допускают большее число значимых символов.)
     Для знаков
    #
    ,
    \
    ,
    X
    ,
    [
    ,
    ]
    ,
    {
    ,
    }
    ,
    !
    ,
    0
    , которых может не быть в некоторых наборах символов, введены трехзнаковые последовательности, начинающиеся с
    ??
    (см. А12.1). Следует заметить, что введение трехзнаковых последовательностей может повредить значения строк, в которых содержатся
    ??
     Введены новые ключевые слова (
    void
    , const
    , volatile
    , signed
    , enum
    ), а мертворожденное слово entry из обращения изъято.
     Для символьных констант и строковых литералов определены новые эскейп-последовательности.
    Объявлено, что появление за
    \
    символов не из принятых эскейп-последовательностей приводит к непредсказуемому результату (см. А2.5.2.)
     Узаконено полюбившееся всем тривиальное изменение: 8 и 9 не являются восьмеричными цифрами.
     Введен расширенный набор суффиксов для явного указания типов констант:
    U
    и
    L
    — для целых и
    F
    и
    L
    — для типов с плавающей точкой. Уточнены также правила определения типа для констант без суффиксов (А2.5).
     Объявлено, что соседние строки конкатенируются.
     Предоставлены средства, позволяющие записывать строковые литералы и символьные константы из расширенного набора символов (А2.6).
     Объекты типа char
    (как и объекты другого типа) можно специфицировать явно со знаком или без знака. Исключается использование словосочетания long float в смысле double
    , но вводится тип long double для чисел с плавающей точкой повышенной точности.
     С некоторых пор доступен тип unsigned char
    . Стандарт вводит ключевое слово signed для явного указания, что объект типа char или другого целочисленного типа имеет знак.
     Уже несколько лет в большинстве реализаций доступен тип void
    . Стандарт вводит void *
    в качестве типа обобщенного указателя; раньше для этой цели использовали char *
    . Одновременно вступают в
    силу правила, по которым запрещается без преобразования типа "смешивать" указатели и целые или указатели разных типов.
     Стандарт устанавливает минимальные пределы диапазонов арифметических типов, предусматривает заголовочные файлы

    и

    , в которых помещаются эти характеристики для каждой конкретной реализации.
     Перечисление — новый тип, которого не было в первой редакции.
     Стандарт заимствует из Си++ способ записи квалификатора типа, в частности квалификатора const
    (A8.2).
     Вводится запрет на модификацию строк; это значит, что их разрешается размещать в памяти, доступной только на чтение (ПЗУ).
     Изменены "обычные арифметические преобразования"; по существу, выполнен переход от принципа "для целых всегда превалирует unsigned
    ; для плавающей точки всегда используется double
    " к принципу "повышение до минимального достаточно вместительного типа" (см. А6.5).
     Отменены старые операторы присваивания вроде
    =+
    . Каждый оператор присваивания теперь представляется одной отдельной лексемой. В первом издании оператор присваивания мог изображаться парой символов, возможно, разделенных символами-разделителями.
     Компиляторам более не разрешается трактовать математическую ассоциативность операторов как вычислительную ассоциативность.
     Введен унарный оператор
    +
    для симметрии с унарным
    -
     Разрешено использовать указатель на функцию в качестве ее именующего выражения без явного оператора
    *
    (см. А7.3.2).
     Структурами разрешено оперировать, при присваиваниях, можно передавать структуры в качестве аргументов функциям и получать их в качестве результата от функций.
     Разрешено применять оператор получения адреса
    &
    к массиву; результатом является указатель на массив.
     В первой редакции результат операции sizeof имел тип int
    ; во многих реализациях он заменен на unsigned
    . Стандарт официально объявляет его зависимым от реализации, но требует, чтобы он был определен в заголовочном файле

    под именем size_t
    . Аналогичное изменение было сделано в отношении типа разности указателей, который теперь выступает под именем ptrdiff_t
    (см. А7.4.8 и А7.7).
     Запрещено применять оператор получения адреса
    &
    к объекту типа register даже тогда, когда данный компилятор не располагает его на регистре.
     Типом результата операции сдвига является тип ее левого операнда; тип правого операнда на повышение типа результата влияния не оказывает (см. А7.8).
     Стандарт разрешает адресоваться с помощью указателей на место, лежащее сразу за последним элементом массива, и позволяет оперировать с такими указателями, как с обычными, см. А7.7.
     Стандарт вводит (заимствованный из Си++) способ записи прототипа функции с включением в него типов параметров и явного указания о возможности их изменения и формализует метод работы с переменным списком аргументов. (См. А7.3.2, А8.6.3, В7.) С некоторыми ограничениями доступен и старый способ записи.
     Стандартом запрещены пустые объявления, т. е. такие, в которых нет объявителей и не объявляется ни одной структуры, объединения или перечисления. Однако объявление с одним тегом структуры
    (или объединения) переобъявит ее даже в том случае, если она была объявлена во внешней области действия.
     Запрещены объявления внешних данных, не имеющие спецификаторов и квалификаторов (т. е. объявления с одним "голым" объявителем).

     В некоторых реализациях, когда extern
    -объявление расположено во внутреннем блоке, его область видимости распространяется на остальную часть файла. Стандарт вносит ясность в эту ситуацию и объявляет, что область видимости такого объявления ограничена блоком.
     Область видимости параметров "вставляется" в составную инструкцию, представляющую собой тело функции, так что объявления на верхнем уровне функции не могут их "затенить".
     Несколько изменены именные пространства идентификаторов. Всем тегам структур, объединений и перечислений стандарт выделяет одно именное пространство; для меток инструкций вводится отдельное именное пространство (см. АИЛ). Кроме того, имена элементов связаны со структурой или объединением, частью которого они являются. (С некоторых пор это общепринятая практика.)
     Допускается инициализация объединения; инициализатор относится к первому элементу объединения.
     Разрешается инициализация автоматических структур, объединений и массивов, хотя и с некоторыми ограничениями.
     Разрешается инициализация массива символов с помощью строкового литерала по точному количеству указанных символов (без '\0'
    ).
     Управляющее выражение и case
    -метки в switch могут иметь любой целочисленный тип.
    1   ...   23   24   25   26   27   28   29   30   31


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