Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
B1.7. Функции обработки ошибок⇐ ПредыдущаяСтр 28 из 28
Многие функции библиотеки в случае ошибки или конца файла устанавливают индикаторы состояния. Эти индикаторы можно проверять и изменять. Кроме того, целое выражение 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 удовлетворяет описанному условию или принадлежит указанному классу символов, и нуль в противном случае.
В наборе семибитовых 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. В таблице на с. 321 переменные s и t принадлежат типу char *, cs и ct – типу const char *, n - типу size_t, а c - значение типа int, приведенное к типу char. Последовательные вызовы strtok разбивают строку s на лексемы. Ограничителем лексемы служит любой символ из строки ct. В первом вызове указатель s не равен NULL. Функция находит в строке s первую лексему, состоящую из символов, не входящих в ct; ее работа заканчивается тем, что поверх следующего символа пишется '\0' и возвращается указатель на лексему. Каждый последующий вызов, в котором указатель s равен NULL, возвращает указатель на следующую лексему, которую функция будет искать сразу за концом предыдущей. Функция strtok возвращает NULL, если далее никакой лексемы не обнаружено. Параметр ct от вызова к вызову может варьироваться. Здесь и ниже под такими выражениями как cs< ct не следует понимать арифметическое сравнение указателей. Подразумевается лексикографическое сравнение, т. е. cs меньше (больше) ct, если первый несовпавший элемент в cs арифметически меньше (больше) соответствующего элемента из ct.— Примеч. ред.
Функции mem... предназначены для манипулирования с объектами как с массивами символов; их назначение - получить интерфейсы к эффективным программам. В приведенной ниже таблице s и t принадлежат типу void *; cs и ct - типу const void *; n - типу size_t; а c имеет значение типа int, приведенное к типу char.
B4. Математические функции: < math.h>
В заголовочном файле < math.h> описываются математические функции и определяются макросы. Макросы EDOM и ERANGE (находящиеся в < errno.h> ) задают отличные от нуля целочисленные константы, используемые для фиксации ошибки области и ошибки диапазона; HUGE_VAL определена как положительное значение типа double. Ошибка области возникает, если аргумент выходит за область значений, для которой определена функция. Фиксация ошибки области осуществляется присвоением errno значения EDOM; возвращаемое значение зависит от реализации. Ошибка диапазона возникает тогда, когда результат функции не может быть представлен в виде double. В случае переполнения функция возвращает HUGE_VAL с правильным знаком и в errno устанавливается значение ERANGE. Если результат оказывается меньше, чем возможно представить данным типом, функция возвращает нуль, а устанавливается ли в этом случае errno в ERANGE, зависит от реализации. Далее x и y имеют тип double, n - тип int, и все функции возвращают значения типа double. Углы в тригонометрических функциях задаются в радианах.
B5. Функции общего назначения: < stdlib.h>
Заголовочный файл < stdlib.h> объявляет функции, предназначенные для преобразования чисел, запроса памяти и других задач. double atof(const char *s)atof переводит s в double; эквивалентна strtod(s, (char**) NULL). int atoi(const char *s)atoi переводит s в int; эквивалентна (int)strtol(s, (char**)NULL, 10). int atol(const char *s)atol переводит 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 (в зависимости от знака), a в errno устанавливается ERANGE. 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 заменяет на size размер объекта, на который указывает p. Для части, размер которой равен наименьшему из старого и нового размеров, содержимое не изменяется. Если новый размер больше старого, дополнительное пространство не инициализируется, realloc возвращает указатель на новое место памяти или, если требования не могут быть удовлетворены, NULL (*p при этом не изменяется). void free(void *р)free освобождает область памяти, на которую указывает p; эта функция ничего не делает, если p равно NULL. В p должен стоять указатель на область памяти, ранее выделенную одной из функций: calloc, malloc или realloc. void abort(void *р)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 пepeдaeт cтpoку s oпepaциoннoй cpeдe для выпoлнeния. Если 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> предоставляет средства для перебора аргументов функции, количество и типы которых заранее не известны. Пусть lastarg - последний именованный параметр функции f с переменным числом аргументов. Внутри f объявляется переменная ap типа va_list, предназначенная для хранения указателя на очередной аргумент: va_list ар;Прежде чем будет возможен доступ к безымянным аргументам, необходимо один раз инициализировать ap, обратившись к макросу va_start: va_start(va_list ap, lastarg);С этого момента каждое обращение к макросу: type va_arg(va_list ap, type);будет давать значение очередного безымянного аргумента указанного типа, и каждое такое обращение будет вызывать автоматическое приращение указателя 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, switсh и циклах, причем только в простых выражениях отношения. 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 равно SIG_IGN, то сигнал игнорируется; в остальных случаях будет выполнено обращение к функции, на которую указывает handler с типом сигнала в качестве аргумента. В число допустимых видов сигналов входят:
signal возвращает предыдущее значение handler в случае специфицированного сигнала, или SIGERR в случае возникновения ошибки. Когда в дальнейшем появляется сигнал sig, сначала восстанавливается готовность поведения " по умолчанию", после чего вызывается функция, заданная в параметре handler, т.е. как бы выполняется вызов (*handler)(sig). Если функция handler вернет управление назад, то вычисления возобновятся с того места, где застал программу пришедший сигнал. Начальное состояние сигналов зависит от реализации. int raise(int sig)raise посылает в программу сигнал sig. В случае неудачи возвращает ненулевое значение.
B10. Функции даты и времени: < time.h>
Заголовочный файл < time.h> объявляет типы и функции, связанные с датой и временем. Некоторые функции имеют дело с местным временем, которое может отличаться от календарного, например в связи с зонированием времени. Типы clосk_t и time_t - арифметические типы для представления времени, a struct tm содержит компоненты календарного времени: int tm_sec; - секунды от начала минуты (0, 61); -- I.B.: все же наверно от 0 до 59int 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 - положительное, если время приходится на сезон, когда время суток сдвинуто на 1 час вперед, нуль в противном случае и отрицательное, если информация не доступна. clock_t clock(void)clock возвращает время, фиксируемое процессором от начала выполнения программы, или -1, если оно не известно. Для выражения этого времени в секундах применяется формула clock()/CLOCKS_PER_SEC. time_t time(time_t *tp)time возвращает текущее календарное время (т. е. время, прошедшее после определенной даты, - обычно после 0 ч 00 мин 00 с GMT 1-го января 1970 г. - примеч. ред.) или -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\0char *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.
B11. Зависящие от реализации пределы: < limits.h> и < float.h>
Заголовочный файл < limits.h> определяет константы для размеров целочисленных типов. Ниже перечислены минимальные приемлемые величины, но в конкретных реализациях могут использоваться и большие значения.
Имена, приведенные в следующей таблице, взяты из < float.h> и являются константами, имеющими отношение к арифметике с плавающей точкой. Значения (если они есть) представляют собой минимальные значения для соответствующих величин. В каждой реализации устанавливаются свои значения.
Содержание Приложение C. Перечень изменений С момента публикации первого издания этой книги определение языка Си претерпело изменения. Почти все нововведения - это расширения исходной версии языка, выполненные так, чтобы сохранилась совместимость с существующими программами; некоторые изменения касаются устранения двусмысленностей первоначального описания, а некоторые представляют собой модификации, привнесенные существующей практикой. Многие из новых возможностей, впоследствии принятые другими разработчиками Си-компиляторов, были первоначально объявлены в документах, прилагаемых к компиляторам. Комитет ANSI, подготавливая стандарт языка, включил большинство этих изменений, а также ввел другие значительные модификации. Некоторые коммерческие компиляторы реализовали их еще до выпуска официального Си-стандарта. В этом приложении сведены воедино различия между языком, определенным в первой его редакции, и той его версии, которая принята в качестве стандарта. Здесь рассматривается только сам язык; вопросы, относящиеся к его окружению и библиотеке, не затрагиваются. Хотя последние и являются важной частью стандарта, но, поскольку в первом издании не делалось попытки описать среду и библиотеку, с соответствующими стандартными элементами сравнивать практически нечего. · В стандарте более тщательно, по сравнению с первым изданием, определено и расширено препроцессирование: в его основу явно положены лексемы; введены новые операторы для " склеивания" лексем (##) и создания символьных строк (#), а также новые управляющие строки, такие как #elif и #pragma; разрешено повторное определение макроса с той же последовательностью лексем; отменена подстановка параметров внутри строк. Разрешено " склеивание" строк с помощью знака \ в любом месте, не только в строках и макроопределениях (см. A.12). · Минимальное число значимых символов всех внутренних идентификаторов доведено до 31; для идентификаторов с внешней связью оно остается равным 6; буквы нижнего и верхнего регистров не различаются. (Многие реализации допускают большее число значимых символов.) · Для знаков #, \, ^, [, ], {, }, |, ~, которых может не быть в некоторых наборах символов, введены трехзнаковые последовательности, начинающиеся с ?? (см. A12.1). Следует заметить, что введение трехзнаковых последовательностей может повредить значения строк, в которых содержатся ?? . · Введены новые ключевые слова (void, const, volatile, signed, enum), а мертворожденное слово entry из обращения изъято. · Для символьных констант и строковых литералов определены новые эскейп- последовательности. Объявлено, что появление за \ символов не из принятых эскейп-последовательностей приводит к непредсказуемому результату (см. A2.5.2.). · Узаконено полюбившееся всем тривиальное изменение: 8 и 9 не являются восьмеричными цифрами. · Введен расширенный набор суффиксов для явного указания типов констант: U и L - для целых и F и L - для типов с плавающей точкой. Уточнены также правила определения типа для констант без суффиксов (A2.5). · Объявлено, что соседние строки конкатенируются. · Предоставлены средства, позволяющие записывать строковые литералы и символьные константы из расширенного набора символов (A2.6). · Объекты типа char (как и объекты другого типа) можно специфицировать явно со знаком или без знака. Исключается использование словосочетания long float в смысле double, но вводится тип long double для чисел с плавающей точкой повышенной точности. · С некоторых пор доступен тип unsigned char. Стандарт вводит ключевое слово signed для явного указания, что объект типа char или другого целочисленного типа имеет знак. · Уже несколько лет в большинстве реализаций доступен тип void. Стандарт вводит void * в качестве типа обобщенного указателя; раньше для этой цели использовали char *. Одновременно вступают в силу правила, по которым запрещается без преобразования типа " смешивать" указатели и целые или указатели разных типов. · Стандарт устанавливает минимальные пределы диапазонов арифметических типов, предусматривает заголовочные файлы < limits.h> и < float.h> , в которых помещаются эти характеристики для каждой конкретной реализации. · Перечисление - новый тип, которого не было в первой редакции. · Стандарт заимствует из C++ способ записи квалификатора типа, в частности квалификатора const (A8.2). · Вводится запрет на модификацию строк: это значит, что их разрешается размещать в памяти, доступной только на чтение (ПЗУ). · Изменены " обычные арифметические преобразования"; по существу, выполнен переход от принципа " для целых всегда превалирует unsigned; для плавающей точки всегда используется double" к принципу " повышение до минимального достаточно вместительного типа" (см. A6.5). · Отменены старые операторы присваивания вроде =+. Каждый оператор присваивания теперь представляется одной отдельной лексемой. В первом издании оператор присваивания мог изображаться парой символов, возможно, разделенных символами-разделителями. · Компиляторам более не разрешается трактовать математическую ассоциативность операторов как вычислительную ассоциативность. · Введен унарный оператор + для симметрии с унарным -. · Разрешено использовать указатель на функцию в качестве ее именующего выражения без явного оператора * (см. A7.3.2). · Структурами разрешено оперировать при присваиваниях, можно передавать структуры в качестве аргументов функциям и получать их в качестве результата от функций. · Разрешено применять оператор получения адреса & к массиву; результатом является указатель на массив. · В первой редакции результат операции sizeof имел тип int; во многих реализациях он заменен на unsigned. Стандарт официально объявляет его зависимым от реализации, но требует, чтобы он был определен в заголовочном файле < stddef.h> под именем size_t. Аналогичное изменение было сделано в отношении типа разности указателей) который теперь выступает под именем ptrdiff_t (см. A7.4.8 и A7.7). · Запрещено применять оператор получения адреса & к объекту типа register даже тогда, когда данный компилятор не располагает его на регистре. · Типом результата операции сдвига является тип ее левого операнда; тип правого операнда на повышение типа результата влияния не оказывает (см. A7.8). · Стандарт разрешает адресоваться с помощью указателей на место, лежащее сразу за последним элементом массива, и позволяет оперировать с такими указателями, как с обычными, см. A7.7. · Стандарт вводит (заимствованный из C++) способ записи прототипа функции с включением в него типов параметров и явного указания о возможности их изменения и формализует метод работы с переменным списком аргументов. (см. A7.3.2, A8.6.3, B7.) С некоторыми ограничениями доступен и старый способ записи. · Стандартом запрещены пустые объявления, т. е. такие, в которых нет объявителей и не объявляется ни одной структуры, объединения или перечисления. Однако объявление с одним тегом структуры (или объединения) переобъявит ее даже в том случае, если она была объявлена во внешней области действия. · Запрещены объявления внешних данных, не имеющие спецификаторов и квалификаторов (т. е. объявления с одним " голым" объявителем). · В некоторых реализациях, когда extern-объявление расположено во внутре |
Последнее изменение этой страницы: 2017-03-14; Просмотров: 396; Нарушение авторского права страницы