在While循环中的表达式周围有双括号

问题描述

我试图这样读取文件

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。 (或其他一些负值)。