$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
在以下代码片段中,为什么表达式100 < strlen(str) - 4
被评估为true?
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[50];
scanf("%s", str);
printf("%d\n", strlen(str) - 4);
if(100 < (strlen(str) - 4))
printf("NOT POSSIBLE!\n");
return 0;
}
终端:
$ gcc so.c -o so
$ ./so
foo
-1
NOT POSSIBLE!
从实验中我发现:
if
表达式的计算结果为true,使得positive_int < negative_num
(这是荒谬的)其中negative_int是strlen
函数调用的形式(参见2.) strlen
替换为硬编码的负整数,则if
会按预期评估为false
。看起来strlen
出现了问题。答案 0 :(得分:4)
由于strlen
的类型为size_t
,4
会转换为(无符号)size_t
,然后从strlen
的返回值中扣除,然后结果与100
进行比较。
6.3.1.8通常的算术转换
....
否则,如果两个操作数都有有符号整数类型或两者都有无符号 整数类型,具有较小整数转换等级类型的操作数是 转换为具有更高等级的操作数的类型。否则,如果具有无符号整数类型的操作数的等级大于或等于 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为带有unsigned的操作数的类型 整数类型。
7.24.6.3 strlen功能
....
size_t strlen(const char *s);
7.19通用定义
....
size_t
这是sizeof
运算符的结果的无符号整数类型;
P.S。顺便提一下,即使在更简单的情况下,也是如此
if (strlen("") < -1)
printf("OK\n");
else
printf("NOK\n");
,输出为OK
。
答案 1 :(得分:4)
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
//your code
}
});
将返回无符号值,因此strlen()
将是无符号数,“非常大”,并且会大于strlen(str) - 4
。
如果您不处理很长的字符串,请尝试将返回值转换为100
。
int
答案 2 :(得分:2)
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[50];
scanf("%49s", str); /* specify size to avoid buffer overrun */
printf("%d\n", (int)strlen(str) - 4);
if(100 < ((int)strlen(str) - 4))
printf("NOT POSSIBLE!\n");
return 0;
}
返回类型为strlen
的无符号整数。当从无符号3中减去4时,无符号整数将包装到最大的可表示数字,因此总是大于100。
答案 3 :(得分:2)
引用C11
,章节§7.23.6.3, strlen()
函数
size_t strlen(const char *s);
strlen()
的返回类型为size_t
,根据章节§7.19,(强调我的)
size_t
这是sizeof运算符的结果的无符号整数类型;
且100
和4
为int
字面值,此处为signed
类型,参见章节§6.4.4.1
整数常量的类型是其值可以在其中的第一个相应列表 代表。
您正在尝试执行涉及signed
类型unsigned
类型的算术运算(减法),因此签名类型会在比较之前升级为unsigned
类型。因此,结果是unsigned类型,比较的最终结果为TRUE。