Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


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.

В таблице на с. 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.— Примеч. ред.

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 (I.B.: вообще-то, функция возвращает int)
char strncmp(cs, ct) сравнивает не более n символов cs и ct; возвращает < 0, если cs< ct, 0, если cs==ct, и > 0, если cs> ct (I.B.: тоже int должна возвращать)
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; более подробное описание этой функции см. ниже

Функции mem... предназначены для манипулирования с объектами как с массивами символов; их назначение - получить интерфейсы к эффективным программам. В приведенной ниже таблице s и t принадлежат типу void *; cs и ct - типу const void *; n - типу size_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. Ошибка области возникает, если аргумент выходит за область значений, для которой определена функция. Фиксация ошибки области осуществляется присвоением errno значения EDOM; возвращаемое значение зависит от реализации. Ошибка диапазона возникает тогда, когда результат функции не может быть представлен в виде 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) десятичный логарифм lg(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 *еxр) разбивает x на два сомножителя, первый из которых - нормализованная дробь в интервале [1/2, 1), которая возвращается, а второй - степень двойки, эта степень запоминается в *exp. Если x - нуль, то обе части результата равны нулю
modf(x, double *ip) разбивается на целую и дробную части, обе имеют тот же знак, что и x. Целая часть запоминается в *ip, дробная часть выдается как результат
fmod(x, y) остаток от деления x на y в виде числа с плавающей точкой. Знак результата совпадает со знаком x. Если y равен нулю, результат зависит от реализации

 

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 с типом сигнала в качестве аргумента. В число допустимых видов сигналов входят:

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

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.

%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 или РМ (до или после полудня)
%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 битов в значении char
SCHAR_MAX UCHAR_MAX или SCHAR_MAX максимальное значение char
CHAR_MIN 0 или CHAR_MIN минимальное значение char
INT_MAX +32767 максимальное значение int
INT_MIN -32767 (I.B.: обычно это значение -32768) минимальное значение int
LONG_MAX +2147463647 максимальное значение long
LONG_MIN -2147483647 (I.B.: обычно это значение -2147483648) минимальное значение long
SCHAR_MAX +127 максимальное значение signed char
SCHAR_MIN -127 (I.B.: обычно это значение -128) минимальное значение signed char
SHRT_MAX +32767 максимальное значение short
SHRT_MIN -32767 (I.B.: обычно это значение -32768) минимальное значение short
UCHAR_MAX максимальное значение unsigned char
UINT_MAX максимальное значение unsigned int
ULONG_MAX максимальное значение unsigned long
USHRT_MAX максимальное значение unsigned short

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

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

 

Содержание

Приложение 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; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.114 с.)
Главная | Случайная страница | Обратная связь