【问题标题】:if statement selects the wrong condition [duplicate]if语句选择了错误的条件[重复]
【发布时间】:2020-12-16 12:07:45
【问题描述】:

我对这段代码有疑问:我不知道为什么它打印 B 而不是 A,因为条件为真。 strlen(x) 明显大于 i。你能帮帮我吗?

#include <stdio.h>
#include <string.h>

int main()
{
   char x[]="Hello";
   int i = -3;
   
   if(strlen(x)>i)
   {
       printf("A");
   }
   else
   {
       printf("B");
   }
    return 0;
}

【问题讨论】:

  • strlen() 返回什么类型的值?
  • 问题是您在无符号比较中使用-3。由于strlen 返回一个size_t,它是一个无符号整数类型,将结果与int 进行比较会导致int 也被转换为size_t
  • 你的编译器应该给你一个警告。如果没有,你绝对应该提高警告级别。

标签: c if-statement strlen


【解决方案1】:

标准函数strlen 声明如下

size_t strlen(const char *s);

其中size_t 类型是实现定义的无符号整数类型,其秩不小于int 类型的秩。通常size_t 类型被定义为unsigned long 类型的别名。

在用作if语句条件的表达式中

if(strlen(x)>i)

编译器使用通常的算术转换来确定操作数的常见类型。也就是说,操作数i 通过传播符号位转换为size_t 类型。因此,转换后的操作数的值是一个非常大的size_t 类型的无符号整数,它大于strlen 调用的返回值。所以条件的计算结果为逻辑假。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    int i = -3;
    
    printf( "( size_t )i = %zu\n", ( size_t )i );
    
    return 0;
}

它的输出可能看起来像

( size_t )i = 18446744073709551613

如果你想在你的程序中得到预期的结果,你应该编写

if( ( int )strlen(x)>i)

例如

if( ( long int )strlen(x)>i)

也就是说,你需要将函数strlen返回的值转换为某个有符号整数类型。

【讨论】:

    【解决方案2】:

    来自C17 document,6.3.1.8,第 39 页

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

    size_t strlen(const char *s);
    

    这里,strlen(x) 返回 size_t 类型的值(无符号长整型)。但是i 的类型是intsize_t 的等级高于int 的等级。因此,i 将被提升为 size_t

    -3 的未赋值值为 4294967293(在我的系统中)。和 strlen(x) = 5 ,所以它会打印 else 语句。

    【讨论】:

      【解决方案3】:

      您正在尝试将有符号整数与无符号整数进行比较。 尝试 if(signed(strlen(x))&gt;i){} 否则,您可以将 I 的值更改为正整数。

      【讨论】:

      • 但是-3 downcast to unsigned 应该仍然小于 strlen of hello,还是我误解了 downcast 的作用?
      • 试试看。int I=-3;printf("%u",(unsigned int)I);然后运行你的代码,你会得到像 4294967293 这样大于 5 的值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      相关资源
      最近更新 更多