u8 num[] = {0x00, 0x00, 0x40};
u8*ptr = num;
u8 tag;
u16 len;
tag = *ptr++;
len = (u16)*ptr++ <<8 | *ptr++;
我期望 len = 0x0040
但 len 在 visual studio 2013 中设置为 0x0000
。
我不知道为什么会这样。
你能从运算符优先的角度解释一下吗?
最佳答案
关于运算符优先级,我建议你先看看这个table .
现在,++/--
可能是棘手的运算符,因为您需要确定它们是前缀运算符还是后缀运算符,正如您在表中看到的那样,如果它们是前缀运算符,它们的优先级与 *
相同(取消引用)。
那么,让我们分析一下最后一行 len = (u16)*ptr++ <<8 | *ptr++;
发生了什么, 有这组运算符 {=, (cast), *(dereference), ++(postfix), <<, |}
, 所以评价顺序按照这个table将是 ++(postfix), *dereference, (type), <<, |, =
这与评估顺序有关,但您需要考虑:
Postfix increment/decrement have high precedence, but the actual increment or decrement of the operand is delayed (to be accomplished sometime before the statement completes execution).
也就是说,这里有几种方法可以实现您想要的:
ptr[1]<<8 | ptr[2]
或:
*(ptr+1) <<8 | *(ptr+2)
最后一个建议,当你处理具有相同优先级的运算符时要小心,正如你在表中看到的,结合性可以是从左到右或从右到左。
PS: 当然,生成的 asm 代码将取决于所使用的编译器和配置,这是该行在 Debug模式下的 vs2015 示例:
; 7 : u16 len = (u16)*ptr++ <<8 | *ptr++;
mov ecx, DWORD PTR _ptr$[ebp]
movzx edx, BYTE PTR [ecx]
shl edx, 8
mov eax, DWORD PTR _ptr$[ebp]
movzx ecx, BYTE PTR [eax]
or edx, ecx
mov WORD PTR _len$[ebp], dx
mov edx, DWORD PTR _ptr$[ebp]
add edx, 1
mov DWORD PTR _ptr$[ebp], edx
mov eax, DWORD PTR _ptr$[ebp]
add eax, 1
mov DWORD PTR _ptr$[ebp], eax
快乐编码。
关于c - 在 C 中,*、=、++、<< |运算符(operator),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44161078/