比较C中的负数

时间:2016-01-29 07:46:51

标签: c

我写的程序有问题。该程序将进入if语句,而不应该。 我有两个变量:

size_t len = 5;
int    tmp = -1;

当我这样做时:

if (tmp > len)
    ft_putstr("this is crazy");

我打印出“这很疯狂,而-1比我小5! 好的好的。所以我查看了我最喜欢的网站并看到了this

尝试时:

printf("%zu", tmp) 

我看到一个很大的正数。好 !这可能是我的程序进入上述if条件的原因,但是如何让它不进入if条件?感谢

2 个答案:

答案 0 :(得分:5)

这里的问题是你试图将未签名的东西与签名的东西进行比较。这意味着在实际转换完成之前会涉及隐式转换。在这种情况下,signed会转换为unsigned(通常不是人们想要的) - 因此许多编译器都有选项可以在完成后显示警告。

要以一种草率的方式做得更正确,你会写:

 if( (int)tmp > (int)len )

然而,这忽略了size_t可能具有对int来说太大的值的事实。要严格,我们必须处理intsize_t范围相结合的范围可能大于任何可用类型。这意味着您必须在两种情况下处理此问题,因此您将使用tmp<0然后tmp<len(数学上,从len>=0开始)的事实。因此,例如,数学tmp<len将被写为tmp<0 || tmp<len。相反的是tmp>=0 && tmp >= len。因此,您应该写道:

 if( tmp >= 0 && tmp > len )

请注意,转换不是问题,tmp可以在第一次检查转换为无符号而不更改值后,intsize_t的不同范围不是问题要么在比较之前将较小的范围转换为更宽的范围。

唯一的问题是,如果您启用了有关无符号签名比较的警告(以检测这些错误),它仍然会发出警告。为了解决这个问题,你需要明确地输入它,但我们知道,一旦我们检查了tmp,转换为无符号就不会改变tmp>=0。所以为了避免警告你会写:

if( tmp >= 0 && (unsigned)tmp > len) )

(unsigned)是因为tmpint,如果tmp是另一种类型,则需要在转换为无符号时尊重该类型。

答案 1 :(得分:0)

您必须了解不同变量类型之间的区别。 intunsignedsize_t等变量类型具有不同的行为,并根据您获得的结果。

如果你真的想要比较两个数字,它们都必须在同一级别(变量类型),否则你会得到意想不到的结果。

以下将解决您的问题。

if(tmp > (int)len)
    ft_putstr("this is crazy");

正如@jblixr建议的那样(感谢评论),您可能需要处理sizeof这些变量类型,并确保在将值从一种数据类型转换为另一种数据类型时不会丢失这些值