Почему несовместимые строки в C FAQ вопрос 16.7? - PullRequest
3 голосов
/ 29 мая 2011

C, часто задаваемые вопросы, вопрос 16.7: http://c -faq.com / fantasticprob / ptralign.html

У меня вопрос по поводу строки:

s.i32 |= (unsigned)(*p++ << 8);

Я понимаю, как работает эта строка кода, но я не понимаю, почему она не просто написана так:

s.i32 |= (long) *p++ << 8;

или

s.i32 |= (unsigned)*p++ << 8; 

Почему так?

===========================

struct mystruct {
    char c;
    long int i32;
    int i16;
} s;

char buf[7];
unsigned char *p;
fread(buf, 7, 1, fp);
p = buf;

s.c = *p++;

s.i32 = (long)*p++ << 24;
s.i32 |= (long)*p++ << 16;
s.i32 |= (unsigned)(*p++ << 8); // line in question
s.i32 |= *p++;

s.i16 = *p++ << 8;
s.i16 |= *p++;

============

Обновление:

Мне до сих пор не ясно, почему необходимо выполнить приведение после операции сдвига для рассматриваемой линии. Может быть, как сказал littleadv: «Это пример, а не единственная возможность».

Если что-то не так с двумя предложенными мною альтернативами, пожалуйста, добавьте свой ответ. На данный момент я выбираю комментарий littleadv в качестве ответа, хотя порядок приоритета для cast и << на самом деле меня не смущал. </p>

P.S. Я не смог направить вопрос автору часто задаваемых вопросов, потому что он больше не принимает вопросы по электронной почте.

1 Ответ

6 голосов
/ 29 мая 2011

Поскольку приведение выше << в порядке приоритета , и вы хотите, чтобы приведение происходило в результате <<.

редактировать для уточнений

Причина, по которой приведение происходит до смещения на long и после смещения на unsigned, объясняется в другом вопросе с тем же кодом :

"В этом коде предполагается, что getc читает 8-битные символы и что данные хранятся в старшем значащем байте вначале (" big endian "). Приведения к (длинному) гарантирует, что 16- и 24-битные сдвиги работать с длинными значениями (см. вопрос 3.14), а приведение к (без знака) защищает от расширения знака. (В целом, при написании кода более безопасно использовать все типы без знака, но см. вопрос 3.19.) ".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...