【问题标题】:Default int type: Signed or Unsigned?默认 int 类型:有符号还是无符号?
【发布时间】:2010-12-06 00:34:53
【问题描述】:

当使用类 C 语言编程时,“默认”整数类型应该是 int 还是 uint/unsigned int?默认情况下,我的意思是当您不需要负数但任何一个都应该足够大以容纳您所持有的数据时。我可以为两者都想出好的论据:

有符号:在数学上表现更好,如果您在某些您没有想到的边界情况下尝试低于零,则出现奇怪行为的可能性较小,通常可以更好地避免奇怪的极端情况。

unsigned:为防止溢出提供一点额外保证,以防万一您对值的假设是错误的。用作说明变量所代表的值从不为负数的文档。

【问题讨论】:

    标签: language-agnostic coding-style


    【解决方案1】:

    作为一个粗略的经验法则,我使用无符号整数来计算事物,并使用有符号整数来衡量事物。

    如果您发现自己从 unsigned int 中递减或减去,那么您应该处于已经期望非常小心不要下溢的上下文中(例如,因为您在一些低级代码中后退从字符串的末尾开始,所以你当然首先要确保字符串足够长以支持这一点)。如果您不在这样的环境中,绝对不能低于零,那么您应该使用带符号的值。

    在我的用法中,无符号整数适用于绝对不能为负的值(或百万分之一的情况,您实际上需要模 2^N 算术),而不适用于恰好不是负数的值,在可能是当前的实现。

    【讨论】:

      【解决方案2】:

      Google C++ Style Guide 对无符号整数有一个有趣的看法:

      (引用如下:)

      关于无符号整数

      有些人,包括一些教科书作者,建议使用无符号类型来表示从不为负的数字。这是一种自我记录的形式。然而,在 C 语言中,此类文档的优势被它可能引入的真正错误所抵消。考虑:

      for (unsigned int i = foo.Length()-1; i >= 0; --i) ...
      

      这段代码永远不会终止!有时 gcc 会注意到这个错误并警告你,但通常不会。比较有符号和无符号变量时,也会出现同样严重的错误。基本上,C 的类型提升方案会导致无符号类型的行为与预期不同。

      因此,使用断言记录一个变量是非负的。不要使用无符号类型。

      (结束引用)

      【讨论】:

      • 实际上,我认为 C 的类型提升方案导致 signed int 的行为与人们预期的不同。无符号整数表现得很好,如果你知道模算术,而有符号整数具有依赖于实现的行为和到处都是有趣的转换。但是如果你只打算使用一个,为了避免混合它们,它必须被签名。所以我同意 unsigned int 不应该随意使用的结论,但实际上我认为向下循环也不应该随意使用......
      • 自从 GCC 无法像往常一样警告unsigned >=0 以来,已经有很长时间了。谷歌指南充其量是误导,最坏的情况是危险,因为循环迭代器的一个非常常见且非常正确的类型将是无符号类型size_t。使用零源计数器向后计数时,无符号下溢的正确测试是 i != ~0U
      • @GregA.Woods:如果i 大于或小于unsignedi~0u 之间的比较将失败。如果i 是至少与unsigned 一样大的任何无符号类型,则i+1u 与0u 的比较将起作用,尽管不是递减i 然后查看结果,更好的方法可能是比较@987654334 @ 为零。
      【解决方案3】:

      提供更具体的类型赋值(如 unsigned int)可以传达有关变量使用的更多信息,并且可以帮助编译器跟踪您分配“不正确”值的任何时间。例如,如果您使用变量来跟踪对象/元素的数据库 ID,则(可能)永远不应该有 ID 小于零(或一)的时间;在这种情况下,不是断言该状态,而是使用无符号整数值将该语句传达给其他开发人员以及编译器。

      【讨论】:

        【解决方案4】:

        未签名的您不会得到太多“防止溢出的保证”。与签名相比,您可能会得到不同但奇怪的行为,但稍晚一些......也许最好提前得到这些假设?

        【讨论】:

        • 在C中,定义了无符号溢出;有符号溢出是未定义。这对我来说是“防止溢出的保证”。
        【解决方案5】:

        我怀疑是否有一个非常好的与语言无关的答案。语言之间以及它们处理混合类型的方式有很多差异,以至于没有一个答案对所有人(甚至大多数人)都有意义。

        在我最常使用的语言中,我使用带符号的,除非我有特定的理由不这样做。不过,这主要是 C 和 C++。用另一种语言,我可能会给出不同的答案。

        【讨论】:

          【解决方案6】:

          当然签了。如果溢出让您担心,那么下溢应该让您更担心,因为意外地“低于零”比超过 int-max 更容易。

          “无符号”应该是一个有意识的选择,让开发人员考虑潜在的风险,只在你绝对确定你永远不会消极(甚至不小心)并且你需要额外的价值空间的情况下使用。

          【讨论】:

          • +1,谢谢,我只是想问同样的问题。这一点对我来说是关键:“......你需要额外的价值空间。”
          【解决方案7】:

          我倾向于使用有符号,除非我知道我需要无符号,因为 int 通常是有符号的,并且键入 unsigned int 需要更多的努力,而 uint 可能会导致其他程序员稍作停顿思考值可以是什么。

          所以,我认为默认为无符号没有任何好处,因为普通的 int 是有符号的。

          【讨论】:

          • +1 我要更强烈地声明:大多数程序员的期望(特别是如果来自,比如说,Java)是默认签名的int。在代码中看到 int 并显示未签名的行为会很奇怪。
          猜你喜欢
          • 2022-01-03
          • 1970-01-01
          • 1970-01-01
          • 2019-09-10
          • 1970-01-01
          • 2013-06-23
          相关资源
          最近更新 更多