我正在分析一个场景:
char str[] = ""; // Understand
如果我理解strlen(str)
,它就会变为0.这没关系。
printf(" %d, %ul, %u, %d, %ul, %u",
strlen(str),
strlen(str),
strlen(str),
strlen(str) - 1,
strlen(str) - 1,
strlen(str) - 1);
输出是:
0,0l,0,-1,4294967295l,4294967295
我也理解这些。
for (int i = 0; i < strlen(str) - 1; i++)
{
}
我不明白strlen(str) - 1
循环条件中for
的价值。
strlen(str) - 1
在for循环中给出值4294967295。
这是为什么?为什么不-1?
答案 0 :(得分:16)
strlen
返回size_t
,这是一个无符号整数。因此,如果strlen(str)-1
为SIZE_MAX
,size_t
会产生strlen(str)
(最大值0
可以容纳)。
您应该使用%zu
来打印size_t
值。
答案 1 :(得分:3)
本声明
printf(" %d, %ul, %u, %d, %ul, %u", strlen(str),strlen(str),strlen(str),strlen(str)-1,strlen(str)-1,strlen(str)-1);
表示当strlen( str ) - 1
像无符号整数一样输出时,例如使用格式说明符%ul
,其值为4294967295l
在循环的条件下
for (int i=0;i<strlen(str)-1;i++)
编译器必须确定左右操作数的公共类型,以确定条件结果的类型
i<strlen(str)-1
右操作数strlen(str)-1
的类型为size_t
(函数strlen
的返回类型为size_t
)。它是无符号整数类型,通常对应unsigned long
。它不能有负值。存储在此类对象中的任何值都将被解释为非负值,并且输出显示strlen(str)-1
的值等于4294967295l
。 (如果使用类型说明符%zu
,则可以获得实际值,因为size_t
甚至可以对应无符号长整数也可能不会被排除。
右操作数的类型为int
。它的等级至少不大于size_type的等级。因此,两个操作数都转换为类型size_t
并具有非负值。
这种确定常见类型的过程称为通常的算术转换。
很明显4294967295l
大于0.因此,如果循环没有break语句,循环将迭代4294967295l
次。
如果以下列方式重写循环中的条件,则可以得到预期的结果
for ( int i = 0; i < ( int )strlen( str ) - 1; i++ )