【发布时间】:2021-01-11 06:06:23
【问题描述】:
我有一个非常简单的 C 程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
FILE* f = fopen("file.txt", "r");
char c;
while (fscanf(f, "%c", &c) == 1) {
printf("char: %c\n", c);
}
}
效果很好,一次从文件中读取一个字符。但是,如果我将 while 循环的条件更改为while (fscanf(f, "%c", &c) != 0),程序似乎会陷入打印一些空白字符的无限循环中。我查看了程序集,除了一条指令外,它们是相同的:
== 1 version
...
40068a: be 5d 07 40 00 mov $0x40075d,%esi
40068f: 48 89 c7 mov %rax,%rdi
400692: b8 00 00 00 00 mov $0x0,%eax
400697: e8 94 fe ff ff callq 400530 <__isoc99_fscanf@plt>
40069c: 83 f8 01 cmp $0x1,%eax
40069f: 74 c9 je 40066a <main+0x24>
4006a1: b8 00 00 00 00 mov $0x0,%eax
4006a6: c9 leaveq
4006a7: c3 retq
4006a8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
4006af: 00
!= 0 version
40068a: be 5d 07 40 00 mov $0x40075d,%esi
40068f: 48 89 c7 mov %rax,%rdi
400692: b8 00 00 00 00 mov $0x0,%eax
400697: e8 94 fe ff ff callq 400530 <__isoc99_fscanf@plt>
40069c: 85 c0 test %eax,%eax
40069e: 75 ca jne 40066a <main+0x24>
4006a0: b8 00 00 00 00 mov $0x0,%eax
4006a5: c9 leaveq
4006a6: c3 retq
4006a7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
唯一的区别是test 与cmp。就我对阅读汇编的了解而言,我看不出有什么区别。那么导致行为差异的原因是什么?
【问题讨论】:
-
也许
fscanf也可能返回EOF(可能是负数) -
与特定的非零值比较应该不同于与零比较。
-
想一想,
fscanf()的可能返回值是多少?在==1的情况下会发生什么,在!=0的情况下会发生什么你可以期待的所有可能的返回值。 -
@IronMan
EOF必须为负数,根据 7.21 Input/output <stdio.h> paragraph 3: "...EOF扩展为一个整数常量表达式, int 类型和负值 ..." -
好点,谢谢@AndrewHenle!