问题描述
我试图这样读取文件:
char c;
while ((c = fgetc(fp) != EOF)) { ... }
并且没有进入循环。为什么此代码不起作用?
我意识到错误未能将包裹括号放在与EOF
的不等于比较之前,例如:
char c;
while ((c = fgetc(fp)) != EOF) { ... }
但是,我不明白为什么第一个条件不起作用。我用
printf("%d",c = fgetc(fp) != EOF)
,并返回1
。因此,问题一定与将条件包装在(...)
括号内有关,这似乎使它的计算结果为while ( (1) )
。
我敢打赌我对RE:操作员关联顺序有误解,但在这里不确定错误的根源。
解决方法
条件表达式取决于运算的优先级。
实际上在while循环中
while ((c = fgetc(fp) != EOF)) { ... }
您可以删除一对外部括号,例如
while ( c = fgetc(fp) != EOF ) { ... }
因为它们不会改变条件的语义。
现在根据运算符的优先级,此循环看起来像
while ( c = ( fgetc(fp) != EOF ) ) { ... }
内括号( fgetc(fp) != EOF )
中的表达式作为逻辑表达式被求值为整数0或1。
因此,您将得到其中一个
while ( c = 1 ) { ... }
如果表达式( fgetc(fp) != EOF )
的计算结果为逻辑true或
while ( c = 0 ) { ... }
如果表达式的计算结果为逻辑假。
请注意,变量c
必须声明为类型int
,因为它是函数fgetc
的返回类型,可以返回值EOF
。
int c;
while ( ( c = fgetc(fp) ) != EOF ) { ... }
否则,您将比较类型为char
的对象和类型为int
的对象,该对象被定义为宏EOF
。
但是,一般来说,类型char
可以像类型unsigned char
一样(取决于编译器选项或默认情况),在这种情况下,由于整数提升,类型为{{1 }}(存储非负值)将永远不等于通常像char
这样定义的EOF
。 (或其他一些负值)。