何时使用无符号值而不是有符号值?

When to use unsigned values over signed ones?

提问人:Bernard 提问时间:8/2/2008 最后编辑:Peter MortensenBernard 更新时间:4/25/2023 访问量:28582

问:

什么时候适合使用无符号变量而不是有符号变量?循环呢?for

我听到了很多关于这个问题的意见,我想看看是否有任何类似于共识的东西。

for (unsigned int i = 0; i < someThing.length(); i++) {  
    SomeThing var = someThing.at(i);  
    // You get the idea.  
}

我知道 Java 没有无符号值,这一定是 Sun Microsystems 的一个深思熟虑的决定。

与语言无关的 类型

评论

2赞 mk12 8/24/2012
我发现这很有帮助:codemines.blogspot.ca/2007/10/......
0赞 NoDataDumpNoContribution 10/9/2014
我认为这个问题是相当基于意见的。提供的代码在这两种情况下都能正常运行,因此您可以同时使用这两种代码。除了性能原因(到目前为止,还没有答案真正涉及性能),这只是个人品味。

答:

82赞 saint_groceon 8/2/2008 #1

我很高兴在这个话题上找到了一个很好的对话,因为我以前没有真正考虑过。

总而言之,如果你要对变量进行算术运算(就像在典型的 for 循环情况下),signed 是一个很好的一般选择——即使你确定所有数字都是正数。

在以下情况下,unsigned 开始更有意义:

  • 你要做一些按位的事情,比如蒙版,或者
  • 迫切希望利用符号位来获得额外的正范围

就我个人而言,我喜欢签名,因为我不相信自己会保持一致并避免将这两种类型混为一谈(就像文章警告的那样)。

评论

9赞 Ben Voigt 4/13/2012
在该线程的后面,它显示它在检测不受信任的输入中的溢出方面非常出色。不幸的是,这个谜题的拟议“答案”并不是那么好。我的是,如果有人使用符号类型有一个同样简单明了的答案,我很想看到它。unsignedtemplate<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); }
10赞 helloandre 8/2/2008 #2

在上面的示例中,当“i”始终为正且较高的范围是有益的时,无符号将很有用。就像你使用“declare”语句一样,例如:

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

尤其是当这些值永远不会改变时。

但是,如果您正在做一个会计程序,其中人们对他们的钱不负责任并且经常处于亏损状态,那么您肯定会想要使用“签名”。

我确实同意 saint 的观点,尽管一个好的经验法则是使用 signed,C 实际上默认为,所以你被覆盖了。

6赞 Mark Harrison 8/2/2008 #3

size_t通常是一个不错的选择,或者如果您使用的是 STL 类。size_type

评论

0赞 mk12 8/24/2012
仅当您处理以字节为单位的大小时。
2赞 underscore_d 6/25/2019
@mk12标准库容器公开元素计数的成员,而不仅仅是字节数。它应该被使用,而不是在可用的地方使用,但暗示任何以 开头的东西都只能表示字节是不准确的。size_typestd::size_tsize_t
8赞 Josh 8/4/2008 #4

当您比较有符号和无符号类型时,C 和 C++ 编译器将生成警告;在示例代码中,您不能使循环变量无符号,并让编译器在没有警告的情况下生成代码(假设已打开上述警告)。

当然,你是用一直向上的警告来编译的,对吧?

而且,您是否考虑过使用“将警告视为错误”进行编译以更进一步?

使用有符号数字的缺点是,它们很容易重载,例如,值 0->n 是菜单选择,而 -1 表示没有选择任何内容 - 而不是创建一个具有两个变量的类,一个用于指示是否选择了某些内容,另一个用于存储该选择的内容。在不知不觉中,你到处都在测试阴性,编译器抱怨你想如何将菜单选择与你拥有的菜单选择数量进行比较 - 但这很危险,因为它们是不同的类型。所以不要那样做。

9赞 Keith Sirmons 11/11/2008 #5

我认为,如果你的商业案例规定负数是无效的,你会希望显示或抛出一个错误。

考虑到这一点,我最近才发现无符号整数,当时我正在处理二进制文件中的数据并将数据存储到数据库中。我故意“破坏”二进制数据,最终得到负值而不是预期的错误。我发现,即使转换了值,该值对我的商业案例也无效。
我的程序没有出错,我最终将错误的数据输入了数据库。如果我使用并让程序失败会更好。
uint

评论

0赞 harmv 3/5/2023
这正是你不应该使用 uint 的原因。如果使用 int,则可以检查无效数据。然后,您可以检查无效(负)值。如果你使用 uint,你的程序不会失败,而只是给出一个巨大的正数。