C中1U和1之间有什么区别吗?
while ((1U << i) < nSize) { i++; }
使用1U
而不是1
任何特殊原因?
在大多数编译器中,两者都会给出具有相同表示的结果。 但是,根据C规范,对带符号参数的位移操作的结果给出了实现定义的结果,因此理论上 1U << i
比1 << i
更便携。 实际上,你遇到的所有C编译器都会将签名左移与无符号左移相同。
另一个原因是如果nSize
是无符号的,那么将它与带符号的1 << i
进行比较将生成编译器警告。 将1
更改为1U
可以消除警告消息,如果i
是31或63,您不必担心会发生什么。
编译器警告很可能是代码中出现1U
的原因。 我建议在打开大多数警告的情况下编译C,并通过更改代码来消除警告消息。
1U未签名。 它可以携带两倍大的值,但没有负值。
根据环境的不同,使用U时,i最大可以是31或15,不会导致溢出。 不使用U,我最多可以是30或14。
31,30是32位int
15,14是16位int
如果nSize是int
,则最大值为2147483647(2 ^ 31-1)。 如果使用1
而不是1U
则1 << 30
将获得1073741824,1 1 << 31
将为-2147483648,因此如果nSize大于1073741824,则while循环将永远不会结束。
使用1U << i
, 1U << 31
将评估为2147483648,因此您可以安全地将其用于nSize,最高可达2147483647.如果nSize是无符号整数,则循环也可能永远不会结束,例如nSize可以大于1U << 31
。
编辑:所以我不同意答案告诉你nSize应该是无符号的,但如果签名那么它不应该是否定的...
1U未签名。
他们在表达式中使用无符号值的原因是(我猜)因为nSize
也是无符号的,并且编译器(当使用某些参数调用时)在比较有符号和无符号值时会发出警告。
另一个原因(在我看来,不太可能,但我们无法知道nSize
应该假设wath值)是无符号值可以是有符号值的两倍,因此nSize
可以达到~4 * 10 ^ 9而不是~2 * 10 ^ 9。