为什么 -1<strlen(s) 等于 0?

why -1<strlen(s) equal to 0?

提问人:Houxiong Yao 提问时间:10/11/2023 最后编辑:Vlad from MoscowHouxiong Yao 更新时间:10/11/2023 访问量:137

问:

    char* s =(char*) "sss";
    int j = -1;
    printf("%d", j < strlen(s));

这主要是关于 j<3 和 j<strlen(s) 之间的区别。

在上面的代码中,printf 功能打印 0,但如果我将 strlen(s) 更改为 3,结果将变为 1(就像我除外的一样)。 那么是什么原因呢?

c 整数 隐式转换 比较运算符 strlen

评论

3赞 Aconcagua 10/11/2023
看一下 的定义 ;它返回一个 .As is unsigned 并且是常量,有符号且大小小于 ,它也被提升为 。此提升产生的最大值 ,该值永远不会小于任何其他可能的值...strlensize_tsize_t-1intsize_tsize_tsize_t
6赞 Aconcagua 10/11/2023
一个好的编译器应该发出关于比较有符号和无符号值的警告,你没有这样做吗?
0赞 Abderrahmene Rayene Mihoub 10/11/2023
这回答了你的问题吗?为什么不能直接将size_t与负整数进行比较?
1赞 ikegami 10/11/2023
启用编译器的警告。在 gcc 中,我使用 .它本来会发现这个问题的。-Wall -Wextra -pedantic

答:

7赞 Tom Karzes 10/11/2023 #1

返回类型为 ,它是无符号整数类型。当将 a 与 an 进行比较时,应用了“通常的算术转换”。在这种情况下,这意味着操作数(即 )被转换为 ,从而产生大于该值的最大可能值。strlensize_tsize_tintint-1size_tsize_tstrlen

评论

3赞 Aconcagua 10/11/2023
@SergeBallesta 从有符号到无符号的转换不是定义为只要数字保持负数就增加最大值 + 1 吗?对于其他表示来说,这应该也没问题,但对于 2C,它有很好的优势,即位模式是相同的。
1赞 Shawn 10/11/2023
@SergeBallesta C23 将需要 2 的补码。除非您喜欢使用 1970 年代或更早的硬件,否则考虑有符号整数的其他表示形式没有多大意义
0赞 chux - Reinstate Monica 10/11/2023
迂腐:“在这种情况下,这意味着 int 操作数,即 -1,被转换为size_t” --> 是的,这是迄今为止常见的情况,但当范围超过 时,情况正好相反。intsize_t
4赞 Vlad from Moscow 10/11/2023 #2

在此表达式中

j < strlen(s)

编译器首先确定表达式的通用类型,以使用通常的算术转换来执行操作。

表达式的类型是无符号整数类型,通常定义为类型的别名。strlen( s )size_tunsigned long

根据 C 标准(6.3.1.8 常用算术转换):

否则,如果具有无符号整数类型的操作数具有 rank 大于或等于另一个操作数类型的秩,则 具有符号整数类型的操作数将转换为 具有无符号整数类型的操作数。请参阅声明 功能strlen

size_t strlen(const char *s);
^^^^^^

由于类型的秩大于有符号类型的秩,因此比较运算符的左操作数将转换为传播符号位的类型。结果,你会得到一个非常大的无符号值。size_tintsize_t

例如,尝试 printf 的这个调用

printf( "( size_t )-1 = %zu\n", ( size_t )-1 );

评论

2赞 Aconcagua 10/11/2023
...或者在那些保持 32 位的 64 位系统上——即 64 位 Windows......unsigned long longunsigned long