比较操作

时间:2012-03-01 15:53:03

标签: c

  

可能重复:
  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;
}

答案是:::上述程序的输出是:如何在地球上

2 个答案:

答案 0 :(得分:3)

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

在您的情况下,TOTAL_ELEMENTS的类型为size_t,未签名。这意味着您的d也会隐式转换为size_t类型。因此,您的d < TOTAL_ELEMENTS实际上被解释为(size_t) d < TOTAL_ELEMENTS(size_t) -1 < TOTAL_ELEMENTS

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

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

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

答案 1 :(得分:2)

这是因为sizeof_t已映射到无符号长类型,因此-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进行比较会带来预期结果。