long long int a;
scanf("%lld",&a);
printf("n : %lld\n",a);
输入为9223372036854775808 (LLONG_MAX + 1)
但输出为9223372036854775807 (LLONG_MAX)
x64 GNU / Linux,我使用GCC编译器
答案 0 :(得分:9)
scanf
中的溢出会触发未定义的行为。
但是,scanf
的许多流行实现都在内部使用strto...
组中的函数将字符串转换为实际数字。 (或者,更确切地说,它们使用与strto...
函数相同的低级实现原语。)strto...
函数在溢出时生成目标类型的最大值。该实现的副作用是您在测试中观察到的。显然使用strtoll
,在正溢出时产生LLONG_MAX
。
但你不应该依赖它,因为行为是未定义的。
答案 1 :(得分:4)
由于scanf
会将输入限制在有效范围内,但会引发ERANGE
错误,如this question和the manpage中的回答:
如果之前达到输入结尾,则返回值
EOF
要么是第一次成功转换,要么是匹配失败。 如果发生读取错误,也会返回EOF
,在这种情况下会出现错误 设置流的指示符(请参阅ferror(3)),并设置errno 表明错误。
...
ERANGE
整数转换的结果将超过其大小 可以存储在相应的整数类型中。
请注意,语言或POSIX标准并不要求这种行为,但对于许多标准库实现(包括您的标准库实现)来说,这显然是正确的。
答案 2 :(得分:1)
有符号溢出是未定义的行为。任何事情都可能发生。
答案 3 :(得分:1)
这是一种未定义的行为。在此,如果您将该值分配给变量而不是获取 从输入开始,那时你将在编译时收到警告。
答案 4 :(得分:0)
输出将无法预测。 我用简单的int尝试了同一段代码。 我附加了输出。