因此,我了解unsigned
变量只能保留正值,signed
变量可以保持负值和正值。但是,我不清楚为什么有人会使用unsigned
变量?这样有风险吗?我的意思是我个人只是坚持使用signed
变量以防万一。使用unsigned
变量是否有内存/性能优势?
答案 0 :(得分:7)
为您的特定问题选择正确类型的原始数据类型就是正确显示您的意图。例如,虽然数组的大小也可能存储在有符号的类型中(就像Java或C#中的情况一样),但为什么要这样做?数组不能为负数。无论如何,这样做只会使您的计划的读者感到困惑,并且不会给您带来任何好处。
不使用无符号值没有可衡量的性能提升;实际上这样做甚至可能是危险的,因为无符号值可以比相同内存大小的有符号值保存更大的正数,因此在分配时会有缩小转换的风险,例如,数组大小自然无符号到相同内存大小的有符号值:
// While unlikely, truncation can happen
int64_t x = sizeof(...);
// ~~~~^~~~~~~ uint64_t on my system
这些错误通常难以跟踪,但编译器会更好地警告您提交错误。
当然,你应该知道在某些情况下使用无符号整数确实很危险。作为一个例子,我写了一个简单的for
循环。我们不希望值i
为负数,因此我们做出看似正确的决定来使用无符号类型的值:
for(unsigned i = 5; i >= 0; --i)
{
}
但是在这种情况下,循环将永远不会终止,因为0 - 1
的无符号值(在此处的第五次迭代中发生)将是一个很大的正值(这称为环绕) ,从而打败循环终止检查。
例如,这可以像这样解决:
for(unsigned i = 5; (i+1) > 0; --i)
{
}
但这不应该阻止您使用正确的数据类型。只需谨慎对待价值范围和环绕等事情,你就可以了。
总之,使用最合适的类型,似乎表明您的意图最好。
答案 1 :(得分:1)
如果您的值实际上是一个位字段,并且您进行了位操作,则无符号更合适。
如果操作导致溢出,则默认情况下,签名行为是未定义的。
答案 2 :(得分:1)
有符号和无符号数的范围不同。
例如,在32位系统上,有符号整数的范围在-2G和2G-1之间(即-2147483648到2147483647)。