我使用Si Labs IDE在C语言中编程8051。我目前有三个字节:address_byte3, address_byte2, and address_byte1
。然后我将变量address_sum
初始化为unsigned long int
,然后对其执行以下操作...
address_sum=(address_byte3<<16)+(address_byte2<<8)+(address_byte1);
此操作会让我相信address_sum
如果address_byte3, address_byte2, & address_byte1
分别为0x92, 0x56, & 0x78
,那么加载到0xXX925678
的值将为0xXX005678
。相反,我的值为address_byte
。我的逻辑看似合理,但我又是那个写代码的人,所以我有偏见,可能被我自己的无知蒙蔽了。有没有人有一个解决方案或解释为什么array[0][] = {5,B,2}
array[1][] = {9,R,4}
array[2][] = {3,B,1}
array[3][] = {1,R,8}
的值是&#34;丢失&#34;?
谢谢。
答案 0 :(得分:1)
对int
进行计算时,短于int
的变量会提升为int
。您的unsigned long
类型似乎是16位,因此将其移位16位并不能正常工作。
您应该将变量显式地转换为结果类型(address_sum = ((unsigned long)address_byte3<<16) +
((unsigned long)address_byte2<<8) +
(unsigned long)address_byte1;
):
.equal-height
最后一次铸造是多余的,但不会受到伤害。
答案 1 :(得分:1)
由@anatolyg解释的16位int/unsigned
的移位只会导致16位答案。
作为一般推广方案,我避免强制转换,因为随着时间的推移,代码会随着代码的发展而缩小结果,并且维护者会使用更广泛的操作数。
备选方案:
((type_of_target) 1) *
:这将确保每项操作至少目标的宽度。
unsigned long address_sum;
...
address_sum = (1UL*address_byte3<<16) + (1UL*address_byte2<<8) + address_byte1;
分配到目的地,然后操作:
address_sum = address_byte3;
address_sum = address_sum << 8 + address_byte2;
address_sum = address_sum << 8 + address_byte1;
一个鬼鬼祟祟,以为不太令人愉快的单线替代方案。召回* +
更高阶优先级而不是转移
address_sum = (0*address_sum + address_byte3 << 16) +
(0*address_sum + address_byte2 << 8) + address_byte1;
考虑@Eugene Sh.关注并使用8位无符号&#34;字节&#34;。
答案 2 :(得分:0)
我的偏好是chux的变体
更大的申报地址; 字节声明a,b,c;
address =a; address<<=8;
address|=b; address<<=8;
address|=c;
尽管到目前为止所有答案都是最详细的,但应该优化成基本相同的代码。但是必须要测试具体的编译器才能看到。无论如何,8051每次指令一次可以移位多于一位吗?别记得了。