【问题标题】:Why the following code does print "S is Bigger" even though s is smaller? [duplicate]为什么即使 s 更小,下面的代码也会打印“S is Bigger”? [复制]
【发布时间】:2016-10-10 17:33:43
【问题描述】:

以下代码的 sn-p 没有按我的预期工作,当在 Ubuntu 机器上使用 GCC 编译时,以下程序的输出是“S is Bigger”。虽然变量 s 是 -1 并且明显小于 sizeof(buffer) 20。但它仍然打印 S is Bigger

我能做出的唯一合乎逻辑的假设是 C 将变量“s”转换为无符号整数并在“If”条件下使用。 如果我的假设是正确的,为什么 C 会这样做,或者如果我错了,为什么这个 sn-p 会给出这种令人困惑的输出。

#include <stdio.h>

int main(void) {

    int s = -1;
    char buffer[20];

    if(s > sizeof(buffer)){
        printf("S is Bigger");
    }
    return 0;
}

【问题讨论】:

  • sizeof(buffer) 会给你指针的大小,在 32 位机器上是 4
  • @MaxB buffer 是数组而不是指针。
  • 整数提升。不要比较有符号和无符号。或投其中之一。你的编译器应该警告有符号和无符号之间的比较。
  • 参见:stackoverflow.com/questions/2084949/arithmetic-operations-on-unsigned-and-signed-integers。
  • 是的,但是,缓冲区大小怎么可能小于-1

标签: c if-statement int sizeof


【解决方案1】:

你是对的,编译器将s转换为unsigned int数据类型size_t(这是sizeof运算符的返回值)。所以比较变成了(在我的 size_t 是 64 位的系统上):

if (18446744073709551615 > 20)

这显然是真的;)

这是标准定义的隐式转换的一部分。相关部分是标准 6.3.1.8 中的“常用算术转换”。

另请参阅此post 和此其他post

基本规则:

  • 如果两个操作数的类型相同,则无需进一步转换。
  • 如果两个操作数都是相同的整数类型(有符号或无符号),则具有较小整数转换等级的操作数将转换为具有较高等级的操作数类型。
  • 如果无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则将有符号整数类型的操作数转换为无符号整数类型的操作数的类型。
  • 如果带符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为带符号整数类型的操作数的类型。
  • 否则,两个操作数都将转换为与带符号整数类型的操作数的类型相对应的无符号整数类型。

【讨论】:

    【解决方案2】:

    来自this问题的回答

    如果 int 为零或正数,它是安全的。如果它是负数,并且 size_t 的等级等于或高于 int,则 int 将转换为 size_t,因此它的负值将变为正值。

    sizeof() 返回 size_t

    【讨论】:

    • 当一个新问题的答案与现有的(已回答的)问题(几乎)相同时,不要将该答案(部分)作为新问题的答案:要么标记新问题作为副本,或发表评论并附上现有答案的链接。
    • @CristiFati 这没关系 IMO。这不是一个重复的问题,因为另一个问题没有询问关于比较负值的问题,并且“重复”功能说它是针对重复的问题。
    • @M.M 感谢您的评论。但我不知道要比较的操作数的符号是​​否有任何区别。它是关于提供一个解决方案,该解决方案由(部分)已经作为解决方案(针对单独的问题)提供的东西组成。例如,对指向该外国问题(带有正确答案)的问题的评论是可以的(至少这是我所做的 - 因为我觉得用现有答案回答在道德上不太正确......它意味着为别人的工作获得一些荣誉)。
    • 提供指向原作者的链接视为对原作者的认可
    猜你喜欢
    • 2017-02-26
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2022-07-09
    • 2016-04-14
    • 1970-01-01
    相关资源
    最近更新 更多