Содержание

Приложение B. Стандартная библиотека

Настоящее приложение представляет собой краткое изложение библиотеки, утвержденной в качестве ANSI-стандарта. Сама по себе библиотека не является частью языка, однако заложенный в ней набор деклараций функций, а также определений типов и макросов составляет системную среду, поддерживающую стандарт Си. Мы не приводим несколько функций с ограниченной областью применения — те, которые легко синтезируются из других функций, а также все то, что касается многобайтовых литер и специфики, обусловленной языком, национальностью и культурой.

Функции, типы и макросы декларируются в следующих головных файлах:

<assert.h> <float.h> <math.h> <stdarg.h> <stdlib.h>
<ctype.h> <limits.h> <setjmp.h> <stddef.h> <string.h>
<errno.h> <locale.h> <signal.h> <stdio.h> <tlme.h>

Доступ к головному файлу осуществляется при помощи строки препроцессора

#inclnde <головной_файл>

Головные файлы можно включать в любом порядке и сколько угодно раз. Строка #include не должна быть внутри внешней декларации или определения и должна встретиться раньше, чем что-нибудь будет востребовано из включаемого головного файла. В конкретной реализации головной файл может и не быть исходным файлом.

Для использования в библиотеке зарезервированы внешние идентификаторы, начинающиеся со знака подчеркивания, а также все другие идентификаторы, начинающиеся с двух знаков подчеркивания или с подчеркивания и заглавной буквы.

B1. Ввод–вывод: <stdio.h>

Определенные в <stdio.h> функции ввода-вывода, а также типы и макросы составляют приблизительно треть библиотеки.

Поток — это источник или получатель данных; его можно связать с диском или с каким-то другим внешним устройством. Библиотека поддерживает два вида потоков: текстовый и бинарный, хотя на некоторых системах, в частности в UNIX`е, они не различаются. Текстовый поток — это последовательность строк; каждая строка имеет нуль или более литер и заканчивается литерой '\n'. Операционная среда может потребовать коррекции текстового потока (например, перевода '\n' в литеры возврат_каретки и перевод_строки).

Бинарный поток — это последовательность непреобразуемых байтов, представляющих собой некоторые промежуточные данные, которые обладают тем свойством, что, если их записать, а затем прочесть той же системой ввода-вывода, то мы получим информацию, совпадающую с исходной.

Поток соединяется с файлом или устройством посредством его открытия, указанная связь разрывается путем закрытия потока. Открытие файла возвращает указатель на объект типа FILE, который содержит всю информацию, необходимую для управления этим потоком. Если не возникает двусмысленности, мы будем пользоваться терминами «файловый указатель» и «поток» как равнозначными.

Когда программа начинает работу, уже открыты три потока: stdin, stdout и stderr.

B1.1. Операции над файлами

Ниже перечислены функции, оперирующие с файлами. Тип size_t — беззнаковый целочисленный тип, используемый для описания результата оператора sizeof.

FILE *fopen(const char *filename, const char *mode)

fopen открывает файл с заданным именем и возвращает поток или NULL, если попытка открытия оказалась неудачной. Режим mode допускает следующие значения:

"r" текстовый файл открывается для чтения (от read (англ.) — читать)
"w" текстовый файл создается для записи; старое содержимое (если оно было) выбрасывается (от write (англ.) — писать)
"a" текстовый файл открывается или создается для записи в конец файла (от append (англ.) — добавлять)
"r+" текстовый файл открывается для исправления (т.е. для чтения и для записи)
"w+" текстовый файл создается для исправления; старое содержимое (если оно было) выбрасывается
"a+" текстовый файл открывается или создается для исправления уже существующей информации и добавления новой в конец файла

Режим «исправления» позволяет читать и писать в один и тот же файл; при переходах от операций чтения к операциям записи и обратно должны осуществляться обращения к fflush или к функции позиционирования файла. Если указатель режима дополнить буквой b (например, "rb" или "w+b"), то это будет означать, что файл бинарный. Ограничение на длину имени файла задано константой FILENAME_MAX. FOPEN_MAX ограничивает число одновременно открытых файлов.

FILE *freopen(const char *filename, const char *mode, FILE *stream)

freopen открывает файл с указанным режимом и связывает его с потоком stream. Она возвращает stream или, в случае ошибки, NULL. Обычно freopen используется для замены файлов, связанных с stdin, stdout или stderr, другими файлами.

int fflush(FILE *stream)

Применяемая к потоку вывода fflush производит дозапись всех оставшихся на буфере (еще не записанных) данных; для потока ввода эта функция не определена. Возвращает EOF в случае возникшей при записи ошибки или нуль в противном случае. Обращение вида fflush(NULL) выполняет указанные операции для всех потоков вывода.

int fclose(FILE *stream)

fclose производит дозапись еще незаписанных буферизованных данных, сбрасывает нечитанный буферизованный ввод, освобождает все автоматически запрошенные буфера, после чего закрывает поток. Возвращает EOF в случае ошибки и нуль в противном случае.

int remove(const char *filename)

remove удаляет файл с указанным именем; последующая попытка открыть файл с этим именем вызовет ошибку. Возвращает ненулевое значение в случае неудачной попытки.

int rename(const char *oldname, const char *newname)

rename заменяет имя файла; возвращает ненулевое значение в случае, если попытка изменить имя оказалась неудачной. Первый параметр задает старое имя, второй — новое.

FILE *tmpfile(void)

tmpfile создает временный файле режимом доступа "wb+", который автоматически удаляется при его закрытии или обычном завершении программой своей работы. Эта функция возвращает поток или, если она не смогла создать файл, NULL.

char *tmpnam(char s[L_tmpnam])

tmpnam(NULL) создает стринг, который не совпадает ни с одним из имен существующих файлов, и возвращает указатель на внутренний статический массив. tmpnam(s) запоминает стринг в s и возвращает его в качестве значения функции; длина s должна быть не менее L_tmpnam. При каждом вызове tmpnam генерируется новое имя; при этом гарантируется не более TMP_MAX различных имен за один сеанс работы программы. Заметим, что tmpnam создает имя, но не файл.

int setvbuf(FILE *stream, char *buf, int mode, size_t size)

setvbuf управляет буферизацией потока; к ней следует обращаться прежде, чем будет выполняться чтение, запись или какая-либо другая операция. Режим mode со значением _IOFBF вызывает полную буферизацию, с _IOLBF — «построчную» буферизацию текстового файла, а режим _IONBF отменяет всякую буферизацию. Если параметр buf не есть NULL, то его значение — указатель на буфер, в противном случае под буфер будет запрашиваться память. Параметр size задает размер буфера. Функция setvbuf в случае ошибки выдает ненулевое значение.

void setbuf(FILE *stream, char *buf)

Если buf есть NULL, то для потока stream буферизация выключается. В противном случае вызов setbuf приведет к тем же действиям, что и вызов (void) setvbuf(stream, buf, _IOFBF, BUFSIZ).

B1.2. Форматный вывод

Функции printf осуществляют вывод информации по формату.

int fprintf(FILE *stream, const char *format, ...)

fprintf преобразует и пишет вывод в поток stream под управлением format. Возвращаемое значение — число записанных литер или, в случае ошибки, отрицательное значение.

Форматный стринг содержит два вида объектов: обычные литеры, копируемые в выводной поток, и спецификации преобразования, которые вызывают преобразование и печать остальных аргументов в том порядке, как они перечислены. Каждая спецификация преобразования начинается с % и заканчивается литерой — спецификатором преобразования. Между % и литерой — спецификатором в порядке, в котором они здесь перечислены, могут быть расположены следующие элементы информации:

Ширина, или точность, или обе характеристики могут быть специфицированы при помощи *; в этом случае необходимое число «извлекается» из следующего аргумента, который должен иметь тип int (в случае двух звездочек используются два аргумента).

Литеры–спецификаторы и разъяснение их смысла приведены в табл. B.1. Если за % нет правильной литеры–спецификатора, результат не определен.

Таблица B.1. Преобразования printf

Литера Тип аргумента; вид печати
d, i int; знаковая десятичная запись.
o int; беззнаковая восьмеричная запись (без ведущего 0).
x, X int; беззнаковая шестнадцатиричная запись (без ведущих 0x или 0X), в качестве цифр от 10 до 15 используются abcdef для x и ABCDEF для X.
u int; беззнаковое десятичное целое.
c int; единичная литера после преобразования в unsigned char.
s char *; литеры стринга печатаются, пока не встретится '\0' или не исчерпается количество литер, указанное точностью.
f double; десятичная запись вида [-]mmm.ddd, где количество d специфицируется точностью. По умолчанию точность равна 6; нулевая точность подавляет печать десятичной точки.
e, E double; десятичная запись вида [-]m.dddddde+-xx или запись вида [-]m.ddddddE+-xx, где количество d специфицируется точностью. По умолчанию точность равна 6; нулевая точность подавляет печать десятичной точки.
g, G double; используется %e и %E, если экспонента меньше -4 или больше или равна точности; в противном случае используется %f. Хвостовые нули и точка в конце не печатаются.
p void *; печатает в виде указателя (представление зависит от реализации).
n int *; число литер, напечатанных к данному моменту данным вызовом printf, записывается в аргумент. Никакие другие аргументы не преобразуются.
% никакие аргументы не преобразуются; печатается %.
int printf(const char *format, ...)

printf(...) полностью эквивалентна fprintf(stdout, ...)

int sprintf(char *s, const char *format, ...)

sprintf действует так же, как и printf, только вывод осуществляет в стринг s, завершая его литерой '\0'. Стринг s должен быть достаточно большим, чтобы вмещать результат вывода. Возвращает количество записанных литер, в число которых литера '\0' не входит.

vprintf(const char *format, va_list arg)
vfprintf(FILE *stream, const char *format, va_list arg)
vsprintf(char *s, const char *format, va_list arg)

Функции vprintf, vfprintf и vsprintf эквивалентны соответствующим printf-функциям с той лишь разницей, что переменный список аргументов представлен параметром arg, инициализированным макросом va_start и, возможно, вызовами va_arg. (См. в B7 описание <stdarg.h>.)

B1.3. Форматный ввод

Функции scanf имеют дело с форматным преобразованием при вводе.

int fscanf(FILE *stream, const char *format, ...)

fscanf читает данные из потока stream под управлением format и преобразованные величины присваивает по порядку аргументам, каждый из которых должен быть указателем. Завершает работу, если исчерпался формат. Выдает EOF по исчерпании файла или перед любым преобразованием, если возникла ошибка; в остальных случаях она возвращает количество преобразованных и введенных элементов.

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

Спецификация преобразования определяет преобразование следующего поля ввода. Обычно результат размещается в переменной, на которую указывает соответствующий аргумент. Однако если присваивание подавляется при помощи *, как, например, в %*s, то поле ввода просто пропускается, и никакого присваивания не происходит. Поле ввода определяется как стринг непробельных литер; при этом ввод стринга прекращается при выполнении любого из двух условий: если встретилась пробельная литера или если ширина поля (в случае, когда она указана) исчерпана. Из этого следует, что при переходе к следующему полю scanf может «перешагивать» через границы строк, поскольку литера новая_строка является пробельной. (Под пробельными понимаются литеры пробела, табуляции, новой_строки, возврата_каретки, вертикальной_табуляции и смены_страницы.)

Литера-спецификатор указывает на способ интерпретации поля ввода. Соответствующий аргумент должен быть указателем. Список допустимых литер-спецификаторов приводится в табл. B.2.

Таблица B.2. Преобразования scanf

Литера Данные на вводе; тип аргумента
d десятичное целое; int *.
i целое; int *. Целое может быть восьмеричным (с ведущим нулем) или шестнадцатиричным (с ведущими 0x или 0X).
o восьмеричное целое (с ведущим нулем или без него); int *.
u беззнаковое десятичное целое; unsigned int *.
x шестнадцатиричное целое (с ведущим 0x или 0X или без);
c литеры; char *. Литеры ввода размещаются в указанном массиве в количестве, заданном шириной поля; по умолчанию это количество равно 1. Литера '\0' не добавляется. Пробельные литеры здесь рассматриваются как обычные литеры и поступают в аргумент. Чтобы прочесть следующую литеру, непробельную используйте %1s.
s стринг непробельных литер (записывается без кавычек); char *, указывающий на массив размера достаточного, чтобы вместить стринг и добавляемую к нему литеру '\0'.
e, f, g число с плавающей точкой; float *. Формат ввода для float состоит из необязательного знака, стринга цифр, возможно, с десятичной точкой и необязательной экспоненты, состоящей из E или E и целого, возможно, со знаком.
p значение указателя в виде, в котором printf("%p") его напечатает; void *.
n записывает в аргумент число литер, прочитанных к этому моменту в этом вызове; int *. Никакого чтения ввода не происходит. Счетчик числа введенных элементов не увеличивается.
[...] выбирает из ввода самый длинный непустой стринг, состоящий из литер, заданных в квадратных скобках; char *. В конец стринга добавляется '\0'. Спецификатор вида []...] включает ] в задаваемое множество литер.
[^...] выбирает из ввода самый длинный непустой стринг, состоящий из литер, не входящих в заданное в скобках множество. В конец добавляется '\0'. Спецификатор вида [^]...] включает ] в задаваемое множество литер.
% обычная литера %; присваивание не делается.

Литерам-спецификаторам d, i, n, o, u и x может предшествовать h, если аргумент есть указатель на short (а не int) или l (буква эль), если аргумент есть указатель на long. Литерам-спецификаторам e, f и g может предшествовать l, если аргумент — указатель на double (а не float), или L, если аргумент — указатель на long double.

int scanf(const char *format, ...)

scanf(...) делает то же, что и fscanf(stdin, ...).

int sscanf(char *s, const char *format, ...)

sscanf(s,...) делает то же, что и scanf(...), только ввод литер осуществляет из стринга s.

B1.4. Функции ввода-вывода литер

int fgetc(FILE *stream)

fgetc возвращает следующую литеру из потока stream в виде unsigned char (переведенную в int) или EOF, если исчерпан файл или обнаружена ошибка.

char *fgets(char *s, int n, FILE *stream)

fgets читает не более n-1 литер в массив s, прекращая чтение, если встретилась литера новая_строка, которая включается в массив; кроме того, записывает в массив '\0'. fgets возвращает s или, если исчерпан файл или обнаружена ошибка, NULL.

int fputc(int c, FILE *stream)

fputc пишет литеру c (переведенную в unsigned char) в stream. Возвращает записанную литеру или EOF в случае ошибки.

int fputs(const char *s, FILE *stream)

fputs пишет стринг s (который может не иметь '\n') в stream; возвращает неотрицательное целое или EOF в случае ошибки.

int getc(FILE *stream)

getc делает то же, что и fgetc, но в отличие от последней, если она — макрос, stream может быть вычислен более одного раза.

int getchar(void)

getchar() делает то же, что getc(stdin).

char *gets(char *s)

gets читает следующую строку ввода в массив s, заменяя литеру новая_строка на '\0'. Возвращает s или, если исчерпан файл или обнаружена ошибка, NULL.

int putc(int c, FILE *stream)

putc делает то же, что и fputc, но в отличие от последней, если она — макрос, stream может быть вычислен более одного раза.

int putchar(int c)

putchar(c) делает то же, что putc(c, stdout).

int puts(const char *s)

puts пишет стринг s и литеру новая_строка в stdout. Возвращает EOF, в случае ошибки, или неотрицательное значение, если запись прошла нормально.

int ungetc(int c, FILE *stream)

ungetc отправляет литеру c (переведенную в unsigned char) обратно в stream; при следующем чтении из stream она будет получена снова. Для каждого потока вернуть можно не более одной литеры. Нельзя возвращать EOF. В качестве результата ungetc выдает отправленную назад литеру или, в случае ошибки, EOF.

B1.5. Функции прямого ввода-вывода

size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream)

fread читает из потока stream в массив ptr не более nobj объектов размера size. Она возвращает количество прочитанных объектов, которое может быть меньше заявленного. Для индикации состояния после чтения следует использовать feof и ferror.

size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *stream)

fwrite пишет из массива ptr в stream nobj объектов размера size; возвращает число записанных объектов, которое в случае ошибки меньше nobj.

B1.6. Функции позиционирования файла

int fseek(FILE *stream, long offset, int origin)

fseek устанавливает позицию для stream; последующее чтение или запись будет производиться с этой позиции. В случае бинарного файла позиция устанавливается со смещением offset — относительно начала, если origin равен SEEK_SET; относительно текущей позиции, если origin равен SEEK_CUR; и относительно конца файла, если origin равен SEEK_END. Для текстового файла offset должен быть нулем или значением, полученным при помощи вызова функции ftell. При работе с текстовым файлом origin всегда должен быть равен SEEK_SET.

long ftell(FILE *stream)

ftell возвращает текущую позицию потока stream или -1L, в случае ошибки.

void rewind(FILE *stream)

rewind(fp) делает то же, что и fseek(fp, 0L, SEEK_SET); clearerr(fp).

int fgetpos(FILE *stream, fpos_t *ptr)

fgetpos записывает текущую позицию потока stream в *ptr для последующего использования ее в fsetpos. Тип fpos_t позволяет хранить такого рода значения. В случае ошибки fgetpos возвращает ненулевое значение.

int fsetpos(FILE *stream, const fpos_t *ptr)

fsetpos устанавливает позицию в stream, читая ее из *ptr, куда она была записана ранее при помощи fgetpos. В случае ошибки fsetpos возвращает ненулевое значение.

B1.7. Функции обработки ошибок

Многие функции библиотеки в случае ошибки или конца файла устанавливают индикаторы состояния. Эти индикаторы можно проверять и изменять. Кроме того, целое выражение errno (декларированное в <errno.h>) может содержать номер ошибки, который дает дополнительную информацию о последней из обнаруженных ошибок.

void clearerr(FILE *stream)

clearerr очищает индикаторы конца файла и ошибки потока stream.

int feof(FILE *stream)

feof возвращает ненулевое значение, если для потока stream установлен индикатор конца файла.

int ferror(FILE *stream)

ferror возвращает ненулевое значение, если для потока stream установлен индикатор ошибки.

void perror(const char *s)

perror(s) печатает s и реализационно-зависимое сообщение об ошибке, соответствующее целому значению в errno, т.е. делает то же, что и обращение к функции fprintf вида

fprintf(stderr, "%s: %s\n", s, "сообщение об ошибке")

См. strerror в разд. B3.

B2. Проверки класса литеры: <ctype.h>

Головной файл <ctype.h> декларирует функции, предназначенные для проверок литер. Аргумент каждой из них имеет тип int и должен либо представлять собой EOF, либо быть значением unsigned char, приведенным к int; возвращаемое значение тоже имеет тип int. Функции возвращают ненулевое значение («истина»), когда аргумент c удовлетворяет описанному условию или принадлежит указанному классу литер, и нуль в противном случае.

isalnum(c)
isalpha(c) или isdigit(c) есть истина
isalpha(c)
isupper(c) или islower(c) есть истина
iscntrl(c)
управляющая литера
isdigit(c)
десятичная цифра
isgraph(c)
печатаемая литера кроме пробела
islower(c)
буква нижнего регистра
isprint(c)
печатаемая литера, включая пробел
ispunct(c)
печатаемая литера кроме пробела, буквы или цифры
isspace(c)
пробел, смена_страницы, новая_строка, возврат_каретки, табуляция, вертикальная_табуляция
isupper(c)
буква верхнего регистра
isxdigit(c)
шестнадцатиричная цифра

В наборе семибитовых ASCII-литер печатаемые литеры находятся в диапазоне от 0x20 (' ') до 0x7E ('~'); управляющие литеры — от 0 (NUL) до 0x1F (US) и 0x7F (DEL).

Помимо перечисленных есть две функции, приводящие буквы к одному из регистров:

int tolower(int c)
переводит c на нижний регистр
int toupper(int c)
переводит c на верхний регистр

Если c — буква на верхнем регистре, то tolower(c) выдаст эту букву на нижнем регистре; в противном случае она вернет c. Если c — буква на нижнем регистре, то toupper(c) выдаст эту букву на верхнем регистре; в противном случае она вернет c.

B3. Функции, оперирующие со стрингами: <string.h>

Имеются две группы функций, оперирующих со стрингами. Они определены в головном файле <string.h>. Имена функций первой группы начинаются с str, второй — с mem. Если копирование имеет дело с объектами, перекрывающимися по памяти, то, за исключением memmove, поведение функций не определено. Функции сравнения рассматривают аргументы как массивы элементов типа unsigned char.

В следующей таблице переменные s и t принадлежат типу char *, cs и ct — типу const char *, n — типу size_t, а c — значение типа int, приведенное к типу char.

char *strcpy(s,ct)
копирует стрингct в стринг s, включая '\0'; возвращает s.
char *strncpy(s,ct,n)
копирует не более n литер стринга ct в s; возвращает s. Дополняет результат литерами '\0', если литер в ct меньше n.
char *strcat(s,ct)
конкатенирует ct к s; возвращает s.
char *strncat(s,ct,n)
конкатенирует не более n литер ct к s, завершая s литерой '\0'; возвращает s.
char strcmp(cs,st)
сравнивает cs с ct; возвращает <0, если cs<ct, 0, если cs==ct, и >0, если cs>ct.
char strncmp(cs,ct)
сравнивает не более n литер cs и ct; возвращает <0, если cs<ct, 0, если cs==ct, и >0, если cs>ct.
char *strchr(cs,c)
возвращает указатель на первое вхождение c в cs или, если такового не оказалось, NULL.
char *strrchr(cs,c)
возвращает указатель на последнее вхождение c в cs или, если такового не оказалось, NULL.
size_t strspn(cs,ct)
возвращает длину начала cs, состоящего из литер, входящих в стринг ct.
size_t strcspn(cs,ct)
возвращает длину начала cs, состоящего из литер, не входящих в стринг ct.
char strpbrk(cs,ct)
возвращает указатель в cs на первую литеру, которая совпала с одной из литер, входящих в ct, или, если такой не оказалось, NULL.
char *strstr(cs,ct)
возвращает указатель на первое вхождение ct в cs или, если такового не оказалось, NULL.
size_t strlen(cs)
возвращает длину cs.
char *strerror(n)
возвращает указатель на реализационно-зависимый стринг, соответствующий номеру ошибки n.
char *strtok(s,ct)
strtok ищет в s лексему, ограниченную литерами из ct; (более подробное описание этой функции см. ниже).

Последовательные вызовы strtok разбивают стринг s на лексемы. Ограничителем лексемы может быть любая литера из числа входящих в ct. В первом вызове указатель s не есть NULL. Функция находит в стринге s первую лексему, состоящую из литер, не входящих в ct; ее работа заканчивается тем, что поверх следующей литеры пишется '\0' и возвращается указатель на лексему. Каждый последующий вызов, в котором указатель s равен NULL, выдает указатель на следующую лексему, которую функция будет искать сразу за концом предыдущей. Функция strtok возвращает NULL, если далее никакой лексемы не обнаружено. Параметр ct от вызова к вызову может варьироваться.

Функции mem... предназначены для манипулирования с объектами как с массивами литер; их назначение — получить интерфейсы к эффективным программам. В приведенной ниже таблице s и t принадлежат типу void *; cs и ctconst void *; nsize_t; а c — значение типа int, приведенное к типу char.

void *memcpy(s,ct,n)
копирует n литер из ct в s и возвращает s.
void *memmove(s,ct,n)
делает то же самое, что и memcpy, но работает и в случае «перекрывающихся» объектов.
int memcmp(cs,ct,n)
сравнивает первые n литер cs и ct; выдает тот же результат, что и функция strcmp.
void *memchr(cs,c,n)
возвращает указатель на первое вхождение литеры c в cs или, если среди первых n литер c не встретилась, NULL.
void *memset(s,c,n)
размещает литеру c в первых n позициях стринга s и возвращает s.

B4. Математические функции: <math.h>

В головном файле <math.h> описываются математические функции и определяются макросы.

Макросы EDOM и ERANGE (находящиеся в <errno.h>) задают отличные от нуля целочисленные константы, используемые для фиксации ошибки области и ошибки диапазона; HUGE_VAL определена как положительное double-значение. Ошибка области возникает, если аргумент выходит за область значений, для которой определена функция. Фиксация ошибки области осуществляется установкой EDOM в errno; возвращаемое значение зависит от реализации. Ошибка диапазона возникает в том случае, когда результат функции не может быть представлен в виде double. В случае переполнения функция возвращает HUGE_VAL с правильным знаком и в errno устанавливает ERANGE. При исчезновении порядка функция возвращает нуль, а устанавливается ли в этом случае в errno ERANGE, зависит от реализации.

Далее x и y имеют тип double, n — тип int, и все функции возвращают значения типа double. Углы в тригонометрических функциях задаются в радианах.

sin(x)
синус x
cos(x)
косинус x
tan(x)
тангенс x
asin(x)
арксинус x в диапазоне [-pi/2, pi/2], x в [-1,1]
acos(x)
арккосинус x в диапазоне [0, pi], x в [-1, 1]
atan(x)
арктангенс x в диапазоне [-pi/2, pi/2]
atan2(y,x)
арктангенс y/x в диапазоне [-pi, pi]
sinh(x)
гиперболический синус x
cosh(x)
гиперболический косинус x
tanh(x)
гиперболический тангенс x
exp(x)
экспоненциальная функция ex
log(x)
натуральный логарифм ln(x), x>0
log10(x)
десятичный логарифм log10(x), x>0
pow(x,y)
xy. Ошибка области, если x=0 и y<0 или x<0 и y — не целое
sqrt(x)
корень квадратный x, x>=0
ceil(x)
наименьшее целое в виде double, которое >=x
floor(x)
наибольшее целое в виде double, которое <=x
fabs(x)
абсолютное значение |x|
ldexp(x,n)
x * 2n
frexp(x, int *exp)
разбивает x на два сомножителя, первый из которых — нормализованная дробь в интервале [1/2, 1], которая возвращается, а второй — степень двойки, показатель которой запоминается в *exp. Если x — нуль, то обе части результата равны нулю.
modf(x, double *ip)
x разбивается на целую и дробную части, обе имеют тот же знак, что и x. Целая часть запоминается в *ip, дробная часть выдается как результат.
fmod(x,y)
остаток от деления x на y в виде числа с плавающей точкой. Знак результата совпадает со знаком x. При y==0, результат зависит от реализации.

B5. Функции общего назначения: <stdlib.h>

Головной файл <stdlib.h> декларирует функции, предназначенные для преобразования чисел, запроса памяти и других задач.

double atof(const char *s)

atof переводит s в double; эквивалентна strtod(s, (char**) NULL).

int atoi(const char *s)

переводит s в int; эквивалентна (int) strtol(s, (char**) NULL, 10).

int atol(const char *s)

переводит s в long; эквивалентна strtol(s, (char**) NULL, 10).

double strtod(const char *s, char **endp)

strtod преобразует первые литеры s в double, игнорируя начальные пробельные литеры; запоминает указатель на непреобразованный конец в *endp (если endp не NULL). В случае переполнения она выдает HUGE_VAL с соответствующим знаком, в случае исчезновения порядка — 0; в обоих случаях в errno устанавливается ERANGE.

long strtol(const char *s, char **endp, int base)

strtol преобразует первые литеры s в long, игнорируя начальные пробельные литеры; запоминает указатель на непреобразованный конец в *endp (если endp не NULL). Если base находится в диапазоне от 2 до 36, то преобразование делается в предположении, что на входе — запись числа по основанию base. Если base равен нулю, то основанием числа считается 8, 10 или 16; число, начинающееся с цифры 0, считается восьмеричным, а с 0x или 0X — шестнадцатиричным. Цифры от 10 до base-1 записываются начальными буквами латинского алфавита в любом регистре. В случае основания 16 в начале числа разрешается помещать 0x или 0X. При переполнении функция возвращает LONG_MAX или LONG_MIN (в зависимости от знака), а в errno устанавливается ERANCE.

unsigned long strtoul(const char *s, char **endp, int base)

strtoul работает так же, как и strtol, с той только разницей, что выдает результат типа unsigned long, а в случае переполнения — ULONG_MAX.

int rand(void)

rand выдает псевдослучайное число в диапазоне от 0 до RAND_MAX; RAND_MAX не меньше 32767.

void srand(unsigned int seed)

srand использует seed в качестве «затравки» для новой последовательности псевдослучайных чисел. Изначально параметр seed равен 1.

void *calloc(size_t nobj, size_t size)

calloc возвращает указатель на место в памяти, отведенное для массива nobj объектов, каждый из которых размера size, или, если памяти запрашиваемого объема нет, NULL. Выделенная область памяти обнуляется.

void *malloc(size_t size)

malloc возвращает указатель на место в памяти для объекта размера size или, если памяти запрашиваемого объема нет, NULL. Выделенная область памяти не инициализируется.

void *realloc(void *p, size_t size)

realloc заменяет размер объекта, на который указывает p, на size. Для части, размер которой равен наименьшему из старого и нового размеров, содержимое не изменяется. Если новый размер больше старого, дополнительное пространство не инициализируется. realloc возвращает указатель на новое место памяти или, если требования не могут быть удовлетворены, NULL (*p при этом не изменяется).

void free(void *p)

free освобождает область памяти, на которую указывает p; эта функция ничего не делает, если p есть NULL. В p должен стоять указатель на область памяти, ранее выделенную одной из функций: calloc, malloc или realloc.

void abort(void *p)

abort вызывает аварийное завершение программы, ее действия эквивалентны вызову raise(SIGABRT).

void exit(int status)

exit вызывает нормальное завершение программы. Функции, зарегистрированные при помощи atexit, выполняются в порядке, обратном их регистрации. Производится выталкивание буферов открытых файлов, открытые потоки закрываются, и управление возвращается в среду, из которой был произведен запуск программы. Значение status, передаваемое в среду, зависит от реализации, однако при успешном завершении программы это всегда нуль. Можно также использовать значения EXIT_SUCCESS (в случае успешного завершения) и EXIT_FAILURE (в случае ошибки).

int atexit(void (*fcn)(void))

atexit регистрирует fcn в качестве функции, которая будет вызываться при нормальном завершении программы; возвращает ненулевое значение, если регистрация не может быть сделана.

int system(const char *s)

system передает стринг s операционной среде для выполнения. Если s есть NULL и существует командный процессор, то system возвращает ненулевое значение. Если s не NULL, то возвращаемое значение зависит от реализации.

char *getenv (const char *name)

getenv возвращает стринг среды, связанный с name, или, если никакого стринга не существует, NULL. Детали зависят от реализации.

void *bsearch(const void *key, const void *base,
                size_t n, size_t size,
                int (*cmp) (const void *keyval, const void *datum))

bsearch среди base[0]...base[n-1] ищет элемент с подходящим ключом *key. Функция cmp сравнивает первый аргумент (ключ поиска) со своим вторым аргументом (значением ключа в таблице) и в зависимости от результата сравнения выдает отрицательное число, нуль или положительное значение. Элементы массива base должны быть упорядочены в возрастающем порядке. bsearch возвращает указатель на элемент с подходящим ключом или, если такого не оказалось, NULL.

void qsort(void *base, size_t n, size_t size,
                int (*cmp) (const void *, const void *))

qsort сортирует массив base[0]...base[n-1] объектов размера size в возрастающем порядке. Функция сравнения cmp — такая же, что и в bsearch.

int abs(int n)

abs возвращает абсолютное значение int-аргумента.

long labs(long n)

labs возвращает абсолютное значение long-аргумента.

div_t div(int num, int denom)

div вычисляет частное и остаток от деления num на denom. Результаты запоминаются в int-членах quot и rem структуры div_t.

ldiv_t ldiv(long num, long denom)

ldiv вычисляет частное и остаток от деления num на denom. Результаты запоминаются в long-членах quot и rem структуры ldiv_t.

B6. Диагностика: <assert.h>

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

void assert(int выражение)

Если выражение есть нуль, то

assert(выражение)

напечатает в stderr сообщение следующего вида:

Assertion failed: выражение, file имя_файла, line nnn

после чего будет вызвана функция abort, которая завершит вычисления. Имя исходного файла и номер строки будут взяты из макросов __FILE__ и __LINE__.

Если в момент включения файла <assert.h> было определено имя NDEBUG, то макрос assert игнорируется.

B7. Списки аргументов переменной длины: <stdarg.h>

Головной файл <stdarg.h> предоставляет средства для перебора аргументов функции, количество и типы которых заранее не известны.

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

va_list ap;

Прежде чем будет возможен доступ к безымянным аргументам, необходимо один раз инициализировать ap, обратившись к макросу va_start:

va_start(va_list ap, посларг);

С этого момента каждое обращение к макросу:

тип va_arg(va_list ap, тип);

будет давать значение очередного безымянного аргумента указанного типа, и каждое такое обращение будет вызывать автоматическое продвижение указателя ap, чтобы последний был готов к выдаче следующего аргумента. Один раз после перебора аргументов, но до выхода из f необходимо обратиться к макросу

void va_end(va_list ap);

B8. Далекие переходы: <setjmp.h>

Декларации в <setjmp.h> предоставляют способ отклониться от обычной последовательности «вызов–возврат»; типичная ситуация — необходимость вернуться из «глубоко вложенного» вызова функции на верхний уровень, минуя промежуточные возвраты.

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 не сохраняет значений.

B9. Сигналы: <signal.h>

Головной файл <signal.h> предоставляет средства для обработки исключительных ситуаций, возникающих во время выполнения программы, таких, как прерывание, вызванное внешним источником или ошибкой в вычислениях.

void (*signal(int sig, void (*handler) (int))) (int)

signal устанавливает, как будут обрабатываться последующие сигналы. Если параметр handler имеет значение SIG_DFL, то используется реализационно-зависимая «обработка по умолчанию»; если значение handler равно SIC_ICN, то сигнал игнорируется; в остальных случаях будет выполнено обращение к функции, на которую указывает handler с типом сигнала в качестве аргумента. В число допустимых видов сигналов входят:

SIGABRT аварийное завершение, например, от abort
SIGFPE арифметическая ошибка: деление на 0 или переполнение
SIGILL неверный код функции (недопустимая команда)
SIGINT запрос на взаимодействие, например, прерывание
SIGSEGV неверный доступ к памяти, например, выход за границы
SIGTERM требование завершения, посланное в программу

signal возвращает предыдущее значение handler — в случае специфицированного сигнала, или SICERR — в случае возникновения ошибки.

Когда в дальнейшем появляется сигнал sig, сначала восстанавливается готовность поведения «по умолчанию», после чего вызывается функция, заданная в параметре handler, т.е. как бы выполняется вызов (*handler) (sig). Если handler-функция вернет назад управление, то вычисления возобновятся с того места, в каком застал программу пришедший сигнал.

Начальное состояние сигналов зависит от реализации.

int raise(int sig)

raise посылает сигнал sig в программу. В случае неудачи возвращает ненулевое значение.

B10. Функции даты и времени: <time.h>

Головной файл <time.h> декларирует типы и функции, связанные с датой и временем. Некоторые функции имеют дело с местным временем, которое может отличаться от календарного, например, в связи с зонированием времени. Типы clock_t и time_t — арифметические типы для представления времени, а struct tm содержит компоненты календарного времени:

int tm_sec;
секунды от начала минуты (0, 61)
int tm_min;
минуты от начала часа (0, 59)
int tm_hour;
часы от полуночи (0, 23)
int tm_mday;
число месяца (1, 31)
int tm_mon;
месяцы после января (0, 11)
int tm_year;
годы после 1900
int tm_wday;
дни после воскресенья (0, 6)
int tm_yday;
дни после 1 января (0, 365)
int tm_isdst;
признак светлого времени

Значение tm_isdst — положительное, если время приходится на светлую часть суток, нуль в противном случае и отрицательное, если информация недоступна.

clock_t clock(void)

clock возвращает время, фиксируемое процессором от начала счета программы, или -1, если оно не известно. Для выражения этого времени в секундах применяется формула clock()/CLOCKS_PER_SEC.

time_t time(time_t *tp)

time возвращает текущее календарное время или -1, если время не известно. Если tp не NULL, то возвращаемое значение записывается и в *tp.

double difftime(time_t time2, time_t time1)

difftime возвращает разность time2-time1, выраженную в секундах.

time_t mktime(struct tm *tp)

mktime преобразует местное время, заданное структурой *tp, в календарное, выдавая его в том же виде, что и функция time. Компоненты будут иметь значения в указанных диапазонах. Функция mktime возвращает календарное время или -1, если оно не представимо.

Следующие четыре функции возвращают указатели на статические объекты, каждый из которых может быть изменен другими вызовами.

char *asctime(const struct tm *tp)

asctime переводит время в структуре *tp в стринг вида

Sun Jan 3 15:14:13 1988\n\0
char *ctime(const time_t *tp)

ctime переводит календарное время в местное, что эквивалентно выполнению

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.

%a сокращенное название дня недели.
%A полное название дня недели.
%b сокращенное название месяца.
%B полное название месяца.
%c локальное представление даты и времени.
%d день месяца (01-31).
%H час (24-часовое время) (00–23).
%I час (12-часовое время) (01–12).
%j день года (001–366).
%m месяц (01–12).
%M минута (00–59).
%p локальное представление AM и PM (до и после полудня).
%S секунда (00–61).
%U неделя по счету от начала года (воскресенье — 1-й день недели) (00–53).
%w день недели (0–6, номер воскресенья есть 0).
%W неделя по счету от начала года (понедельник — 1-й день недели) (00–53).
%x локальное представление даты.
%X локальное представление времени.
%y год без указания века (00–99).
%Y год с указанием века.
%Z название временной зоны, если оно есть.
%% %.

B11. Реализационно-зависимые пределы: <limits.h> и <float.h>

Головной файл <limits.h> определяет константы для размеров целочисленных типов. Ниже перечислены минимальные приемлемые величины, но в конкретных реализациях могут использоваться и большие значения.

CHAR_BIT 8 бит в значении char
CHAR_MAX UCHAR_MAX или SCHAR_MAX максимальное значение char
CHAR_MIN 0 или SCHAR_MIN минимальное значение char
INT_MAX +32767 максимальное значение int
INT_MIN -32767 минимальное значение int
LONG_MAX +2147483647 максимальное значение 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

Имена, приведенные в следующей таблице, взяты из <float.h> и являются константами, имеющими отношение к арифметике с плавающей точкой. Значения (если они есть) представляют собой минимальные значения для соответствующих величин. В каждой, реализации устанавливаются свои значения.

FLT_RADIX 2 основание представления экспоненты: например, 2, 16
FLT_ROUNDS способ округления при сложении чисел с плавающей точкой
FLT_DIG 6 количество верных десятичных цифр
FLT_EPSILON 1E-5 минимальное x, такое, что 1.0 + x != 1.0
FLT_MANT_DIG количество цифр по основанию FLT_RADIX в мантиссе
FLT_MAX 1E+37 максимальное число с плавающей точкой
FLT_MAX_EXP максимальное и, такое, что FLT_RADIXn-1 представимо
FLT_MIN 1E-37 минимальное нормализованное число с плавающей точкой
FLT_MIN_EXP минимальное я, такое, что 10n представимо в виде нормализованного числа
DBL_DIG 10 количество верных десятичных цифр для типа double
DBL_EPSILON 1E-9 минимальное x, такое, что 1.0 + x != 1.0, где x принадлежит типу double
DBL_MANT_DIG количество цифр по основанию FLT_RADIX в мантиссе для чисел типа double
DBL_MAX 1E+37 максимальное число с плавающей точкой типа double
DBL_MAX_EXP максимальное в, такое, что FLT_RADIXn-1 представимо в виде числа типа double
DBL_MIN 1E-37 минимальное нормализованное число с плавающей точкой типа double
DBL_MIN_EXP минимальное n, такое, что 10n представимо в виде нормализованного числа типа double