【问题标题】:Double parenthesis around expression in While loopWhile循环中表达式周围的双括号
【发布时间】:2020-08-18 20:51:18
【问题描述】:

我正试图读取这样的文件:

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:运算符关联顺序,但不确定这里错误的根源。

【问题讨论】:

  • 我不确定如何解释与printf 的区别,但charc 的错误类型; fgetc 返回一个int,因为EOF 不应与任何char 冲突。
  • 不是双括号有区别,而是!=higher precedence= 多。
  • 赋值表达式在赋值之后具有左操作数的值,这意味着 c = fgetc(fp) 将是 ascii 字符碰巧具有的任何值。尝试在条件之外做作业。
  • 我无法重现这一点。它以c=1 为我进入循环,直到它到达EOF,此时它以c=0 退出。你是如何确定没有进入循环的?
  • @thatotherguy 这是我的错误。我在循环内打印字符以显示正在读取的内容。但是,我将它打印为char,而实际上它正在评估为int,如前所述。所以我想我看到的是垃圾输出或什么都没有。诚然,这不是一个很好的测试方法。

标签: c while-loop char eof fgetc


【解决方案1】:

条件表达式取决于操作的优先级。

其实在这个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 ) 的计算结果为逻辑真或

while ( c = 0 ) { ... }

如果表达式的计算结果为逻辑假。

注意变量c要声明为int类型,因为它是函数fgetc的返回类型,可以返回值EOF

int c;
while ( ( c = fgetc(fp) ) != EOF ) { ... }

否则,您将比较 char 类型的对象和定义为宏 EOFint 类型的对象。

然而,通常char 类型可以表现为unsigned char 类型(取决于编译器选项或默认情况下),在这种情况下,由于整数提升,char 类型的对象(存储一个非负值)永远不会等于通常定义为-1EOF。 (或像其他一些负值)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    相关资源
    最近更新 更多