【问题标题】:unsigned int and signed char comparisonunsigned int 和 signed char 比较
【发布时间】:2011-07-02 13:26:07
【问题描述】:

我正在尝试将 unsigned int 与有符号 char 进行比较,如下所示:

int main(){
  unsigned int x = 9;
  signed char y = -1;
  x < y ? printf("s") : printf("g");
  return 0;
}

我原以为 o/p 是“g”。相反,它的“s”。这里做了什么样的转换?

【问题讨论】:

标签: c char type-conversion unsigned-integer


【解决方案1】:

C99 的 6.3.1.8 部分,通常的算术转换, 详细介绍了隐式整数转换。

如果两个操作数的类型相同,则不需要进一步转换。

这不算数,因为它们是不同的类型。

否则,如果两个操作数都是有符号整数类型或都具有无符号整数类型,则整数转换等级较小的操作数将转换为等级较大的操作数类型。

这不算数,因为一个已签名,另一个未签名。

否则,如果无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。

宾果游戏。 x 的排名高于 y,因此 y 被提升为 unsigned int。这意味着它从-1 变形为UINT_MAX,大大大于9。

其余规则不适用,因为我们找到了匹配项,但为了完整起见,我将它们包括在内:

否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型输入。

否则,两个操作数都转换为无符号整数类型,对应有符号整数类型的操作数。


与此问题相关的排名如下所示。所有排名都在 C99,6.3.1.1 部分,布尔值,字符和整数中详细说明,因此您可以参考以获取更多详细信息。

long long int 的等级应大于long int 的等级,即 大于int的等级,大于short int的等级,大于signed char的等级。

char 的等级应等于signed charunsigned char 的等级。

【讨论】:

  • 很好的解释。我要补充一点,在这种情况下,最好总是施放。选择您希望进行比较的类型,并将 both 转换为该类型:(signed int)x &lt; (signed int)y 将保证您最初期望的结果。
  • 实际上,我几乎从不使用无符号整数。如果int 不能保持足够大的值,我会切换到long 甚至long long 如果需要。太多次我被拒绝负数的无符号整数咬伤,使我的许多循环无限,并导致焦虑和咬牙切齿:-)
  • @paxdiablo,我只是做相反的事情,从不尝试使用有符号整数类型。寻址、大小和类似内容的正确类型是size_t,它是无符号的。大多数情况下,这种类型准确地捕获了我想要从整数类型中获得的语​​义。 int 几乎总是人们使用它的错误类型。对我来说有意义的签名类型是ptrdiff_t,仅此而已。
  • 无需费心查找,我认为整数提升是在算术转换之前应用的。所以你说的一切都是真的,但请注意,就算术转换而言,当他们看到 RHS 操作数时,它的类型为 int
【解决方案2】:

运行以下代码:

int main(){
  unsigned int x = 9;
  signed char y = -1;
  printf("%u\n", (unsigned int)y);
  x < (unsigned int)y ? printf("s") : printf("g");
  return 0;
}

输出是:

4294967295 s

在一次强制转换之后,y 的值非常大。这就是为什么输出是 s。

【讨论】:

    【解决方案3】:

    char提升为unsigned int,值为MAX_UINT,大于9。

    【讨论】:

    • 如果它是一个无符号字符,那么有符号字符会被提升为无符号字符吗?
    • @Abhi:是的。第 3 条(请参阅我的回答)仍然以“如果具有无符号整数类型的操作数的等级大于 或等于 ...”开始。
    • @Abhi:不,他们都将被提升为int提供你不是在sizeof(int) == sizeof(char)的一些奇怪的实现中。在这种情况下,两者都会以unsigned int 结尾。因此,(unsigned char)9 &lt; (signed char)-1(粗略地说)如果sizeof(int) &gt; sizeof(char) 为假,如果sizeof(int) == sizeof(char) 为真。我说“松散”是因为重要的是范围而不是大小,但假设int 中没有填充位它们对应。这很愚蠢,但通常不要在完全可移植的代码中对小于int 的类型进行算术运算(包括比较)。
    【解决方案4】:

    我的猜测是 y 被提升为 unsigned int 成为一个很大的价值(由于包装)。因此条件满足。

    【讨论】:

    • 如果您不知道,请不要回答。
    • @Jim Balter:我只是想给 OP 一个提示。如果您认为它的提示不正确,请随意投反对票。
    • 如果给出提示,请说“这里有提示”...并将其添加为问题的评论,而不是答案。提示和猜测不是答案。
    • 感谢您的建议..将在以后的评论/答案中处理。
    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多