嗨考虑这个代码意义:的这个C代码的某些部分不适合我
uint16_t dest_pid;
uint8_t *p;
pf->dest_pid = p[0] + (p[1] << 8) //(p[1] << 8) equals 0 right?
此代码是嵌入式操作系统的驱动程序的一部分。 一些想法可能是这个陈述背后的想法?或者可能是我缺少一些重要的东西?
嗨考虑这个代码意义:的这个C代码的某些部分不适合我
uint16_t dest_pid;
uint8_t *p;
pf->dest_pid = p[0] + (p[1] << 8) //(p[1] << 8) equals 0 right?
此代码是嵌入式操作系统的驱动程序的一部分。 一些想法可能是这个陈述背后的想法?或者可能是我缺少一些重要的东西?
第一:dest_pid
pf
后是从结构的一部分,我认为这是另一个变量则uint16_t dest_pid;
二:p
是一个指向uint8_t
,当你做(p[1] << 8)
你转移什么是里面的指针8,用于举例如果p[1] = 0xE5
在移动后将是0xE500
。请记住,您将结果放在dest_pid
这是一个2字节的变量。
最后一行的翻译是最有可能采取的pid
低字节(少显著),并把它添加到的pid
高字节(8移动),并把它放在pf->dest_pid
,你可能会觉得,为什么他不从一开始就发送2个字节,其原因可能是因为他从一个每单位时间(周期)只发送一个字节的总线获取它。
我假设你的p
是有意义的初始化(指向一些有效的位置)。
然后在p[0] + (p[1] << 8)
的p[1]
将被隐式提升到unsigned
做左移<< 8
之前,所以代码确实使感(例如,在32个如ARM处理器)。非正式地它使得其低8位是从p[0]
和高8位是从p[1]
眼观讲一个16位的数,隐式规则是,在C的算术运算是在int
至少(和从来没有在更小的块数据的如short
或uint8_t
或char
)。但细节更为复杂(并且从C89到C99以及C11标准略有进化)。
假设类型为'uint8_t',由于_integer promotions_,'p [1]'将被隐式转换为'int'(或者如果您愿意,可以是'signed')。在这种情况下没有其他办法。 –
这是正确的,但是p [无论在里面]的类型是八位。 如果它被明确铸造为“.. +(uint16_t)(p [1] << 8)”,我会理解,它将等于p [1] * 256。现在我只看到这个“(eight_bit_var < <8)“(对我来说)意味着零。 –
@RadoslawKrasimirow:你错了:'(eightbitvar << 8)'不是8位操作数移位,而是'int'移位。所以它并不总是零。 –
取消引用未初始化的指针?不知道这个想法是什么,但它肯定不是一个好主意。除非你错过了一些代码? – mathematician1975
'(p [1] << 8)'是表达式的一部分。它有一个类型(无符号),它是从p [1]类型派生出来的:它只能“继承”未签名的质量,而不是大小。 – joop
看这里:http://stackoverflow.com/questions/12131568/bit-shifting-a-byte-by-more-than-8-bit – Downvoter