【问题标题】:comparison operation [duplicate]比较操作[重复]
【发布时间】:2012-03-01 15:53:02
【问题描述】:

可能重复:
Unsigned and signed comparison
A riddle (in C)

#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
   int d = -1;
   if (d < TOTAL_ELEMENTS)
      printf("of course -1 is less than %d",TOTAL_ELEMENTS);
   else
      printf("how on earth");
   return 0;
}

答案是:::上述程序的输出是:到底是怎么回事

【问题讨论】:

标签: c


【解决方案1】:

当您执行混合有符号与无符号比较时(其中有符号类型不大于无符号类型),比较在 无符号 域中执行,即有符号操作数被隐式转换为无符号类型。

在您的情况下,TOTAL_ELEMENTS 的类型为 size_t,它是无符号的。这意味着您的 d 也被隐式转换为 size_t 类型。因此,您的 d &lt; TOTAL_ELEMENTS 实际上被解释为 (size_t) d &lt; TOTAL_ELEMENTS(size_t) -1 &lt; TOTAL_ELEMENTS

(size_t) -1 是一个非常大的正值。它实际上是size_t 类型的最大可能值。因此你得到的结果。

在您的情况下,您显然需要签名比较。为此,您必须将无符号值显式转换为有符号类型(密切注意不要导致溢出)。例如,这将“按预期”工作

if (d < (int) TOTAL_ELEMENTS)
  ...

【讨论】:

    【解决方案2】:

    这是因为sizeof_t 映射到一个unsigned long 类型,所以-1 变成0xFFFFFFFFFFFFFFFF,一个相当大的 整数。试试这个:

    #include<stdio.h>
    #define TOTAL_ELEMENTS(a) ((int)(sizeof((a))/sizeof(*(a))))
    int array[] = {23,34,12,17,204,99,16};
    int main() {
        int d = -1;
        if (d < TOTAL_ELEMENTS(array)) {
            printf("of course -1 is less than %d",TOTAL_ELEMENTS(array));
        } else {
            printf("how on earth");
        }
        return 0;
    }
    

    请注意我如何重写您的宏以引用 array 作为其参数,并向 int 添加强制转换以确保与 -1 进行比较会产生预期的结果。

    【讨论】:

      猜你喜欢
      • 2013-04-04
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多