使用类型转换或使用尾随数据类型标识符。 (uint16_t)10或10u?

时间:2017-05-22 15:41:15

标签: c

为了在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;
}

2 个答案:

答案 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时会变得更糟。也许你应该把演员视为我想我知道我在做什么