2015-09-19 8 views
3

Я читал файл с исходным кодом. Но я застрял по следующей линии:Что означает isspace (ch & 0xff)?

while (isspace (* bp & 0xff)) 
    ++ bp; 

Я знаю, что основная идея состоит в том, чтобы удалить пробелы. Но я не знаю, что именно делает 0xff в следующей функции.

static enum tokens scan (const char * buf) 
{ 
    static const char * bp; 

if (buf) 
    bp = buf;  /* new input line */ 

while (isspace (* bp & 0xff)) 
    ++ bp; 

if (isdigit (* bp & 0xff) || * bp == '.') 
{ 
    errno = 0; 
    token = NUMBER, number = strtod (bp, (char **) & bp); 
    if (errno == ERANGE) 
     error ("bad value: %s", strerror (errno)); 
} 
else 
token = * bp ? * bp ++ : 0; 

    return token; 
} 
+0

Какой тип 'bp'? – edmz

+3

Пожалуйста, покажите нам окружающий код, в частности определение и содержание 'bp'. – orlp

+0

Автор имеет многолетний опыт программирования. И сначала он написал, что как isspace (* bp), но потом он изменил его. Итак, я ищу здесь значимую причину. – Begginer

ответ

3

Эта операция заставляет нули оставить значение.
[OR]
Операция * ч & 0xff выбрать первые 8 битов и isspace проверить, если значение является пространством символ.

+2

Или, принимая 8 наименее значимых бит '* bp'. –

+0

Спасибо, я думаю, что нашел свой ответ. Поскольку char продвигается до int в isspace() с соответствующими авторами, автор хочет убедиться, что он всегда является ansi-c char. Большое спасибо. – Begginer

2

Вычисление операции И с 0xFF извлекает младший байт, предполагая 8 бит на байт. Для неотрицательных значений нет никакого эффекта, но char также может быть подписан, и в этом случае полученный int не может быть представлен в ; взятие младшего байта решает эту проблему.

Технически, в выражении ch & 0xFF операнды повышены до int, которые могли бы испугали программист, так как параметр isspace является int, но значение должно соответствовать в unsigned char или иметь значение EOF, которое только могу будут представлены int с.

+0

Попробуйте следующее: 'char ch = -2; printf ("% d \ n", ch & 0xFF); ' –

+0

@ M.M Спасибо, хорошо, я не рассматривал возможные отрицательные значения. – edmz

4

isspace функция и другие ctype.h функция ожидание int как аргумент. В стандартном разделе C11 7.4/1:

Заголовок объявляет несколько функций, полезных для классификации и отображения символов. Во всех случаях аргумент равен int, , значение которого должно быть представлено как unsigned char или должно быть равно значению макроса EOF. Если аргумент имеет любое другое значение, поведение не определено.

Это означает, что если у вас есть такой код:

char ch = 'é'; // same as: char ch = -126; for some code pages 

isspace(ch); 

, то этот вызов вызывает undefined behaviour.

Основанием для этого является так, что эта функция может быть реализована в виде таблицы перекодировки: #define isspace(x) space_table[x]

Причинение неопределенное поведение плохо, конечно, так isspace(ch) неправильно. Правильный способ исправить код является:

isspace((unsigned char)ch); 

На машине, которая использует 2 в дополнении арифметика, то ch & 0xFF в точности эквивалентен (unsigned char)ch.

На машине, которая не использует дополнение 2, она будет искать неправильное значение (но не вызывать неопределенное поведение).

Возможно, ваш программист был рад предположить, что его код никогда не будет работать на машине с дополнением не-2 с отрицательными кодами символов для пробелов, и он чувствовал, что & 0xFF был более эстетичным, чем актерский состав.

+0

Я не хочу верить, что любой поставщик компилятора когда-либо будет писать isspace (и любую другую такую ​​функцию) таким образом, чтобы он не мог использоваться для 'char c', что бы это ни было в' 'c' ... Можете ли вы показать мне пример такого компилятора? – PiotrNycz

+0

@PiotrNycz Я могу показать только стандарт C, который управляет всеми компиляторами –

+0

Очевидно, что в прошлом был такой компилятор, иначе авторы ANSI C не захотели бы писать стандарт таким образом, чтобы поддерживать такой компилятор –

Смежные вопросы