为了在16位机器中对不同数据类型操作数进行减法运算时得出正确的答案(请参阅下面的代码),我理解将10
更改为10u
将提供正确的答案。
我习惯使用类型转换而不是使用尾随数据类型标识符:使用(uint16_t)10
代替10u
。
首选方式是什么?
我知道10u
输入要少得多。
除了减少输入的好处之外,还有一个重要的原因,10u
是一个更好的方法吗?或者它真的没关系?
#include <stdint.h>
uint16_t u16c;
int32_t s32;
int main()
{
u16c = 100U;
s32 = 10 - u16c;
}
答案 0 :(得分:2)
类型unsigned
通常不是任何特定固定大小类型的同义词。无论10u
的大小如何,表达式unsigned
都将生成unsigned
类型,而表达式(uint16_t)n
将在int
无法表示所有值的平台上生成无符号值0-65535,或者可以在平台上签名的值。在以下情况下,这一点至关重要:
unsigned mul_mod_65536(uint16_t x, uint16_t y)
{ return (x*y) & 65535u; }
32位系统的某些编译器会生成出现故障的代码 某些情况下x和y的乘积超过2147483647,即使是 硬件'乘法指令的低16位是正确的。 可以通过将代码写为:
来更正代码unsigned mul_mod_65536(uint16_t x, uint16_t y)
{ return (1u*x*y) & 65535u; }
请注意,将1转换为(uint16_t)不会修复任何内容,因为那样会
只需转换回签名int
。
答案 1 :(得分:1)
不是答案 - 评论时间太长了。
强制转换的问题在于它隐藏了编译器会选择的警告。例如
uint16_t x = (uint16_t) 70000; /* No warning */
uint16_t y = (uint16_t) -1; /* No warning */
uint16_t z = 70000U; /* Compiler warning */
uint16_t a = -1; /* Compiler warning */
转换为Unicode时会变得更糟。也许你应该把演员视为我想我知道我在做什么