【问题标题】:C++ Strange behaviour for comparison with XOR valueC++ 与 XOR 值比较的奇怪行为
【发布时间】:2015-02-24 14:39:10
【问题描述】:

让我们使用以下程序(称为charco.cpp 并有意以// 开头):

//
#include <iostream>
#include <stdio.h>
int main()
{
    FILE* fp = fopen("charco.cpp", "rt");
    char c = fgetc(fp);
    if(c == '/')
    {
        char c2 = fgetc(fp);
        if(c2 == 122^85) // *** OK
        {
            c2 = fgetc(fp);
            while(c2 != 246^252)  // **** NOT OK
            {
                c2 = fgetc(fp);
            }
        }
    }
}

在其当前版本中,它将永远在**** NOT OK 指示的行中循环,因为它将无法匹配// 之后的结束行字符,因此它会读取整个文件...

但是,如果我将 246 ^ 252 更改为 10(char)(246 ^ 252) 或只是简单地 '\n' 它不会永远循环下去,它会正确匹配,但 (char)246^252 会再次失败。

谁能解释一下为什么会出现这种奇怪的行为? (编译器:g++ 4.9.2)

【问题讨论】:

  • 为什么这个 C++ 问题被标记为c
  • @Borgleader:If he's compiling it with a C++ compiler, it's C++。不是很好的 C++,但是 C++。
  • @fritzone:你到底想做什么?你能抽象出所有这些“将自己读入FILE”的gubbins,然后向我们展示一些你认为错误的XOR 运算符的输入和输出吗?
  • 请注意,fgetc 返回一个 int。另请注意,fopen 的模式 "rt" 参数是非标准的。
  • 当我对优先级存有疑问时,我会参考此页面:en.cppreference.com/w/cpp/language/operator_precedence(或者只是为了安全起见包含括号。)

标签: c++ c file


【解决方案1】:
while (c2 != 246^252)

你在做:

while ((c2 != 246)^252) // Fail, bool^252

如果 c2 != 246,这将给出 253 (0^252)。否则将给出 252。

你必须使用括号:-)

while (c2 != (246^252)) // Correct, c2 != 10

【讨论】:

  • 参考(对 OP)参见例如this operator precedence table.
  • Here's an attempt我曾经做过一个C11优先表。
  • 是的......这也解释了为什么(c2 == 122^85)虽然给出了一个非常奇怪的值却被正确执行......
  • @Lundin 我会把它打印出来并贴在墙上以提醒这一天......实际上我已经查看了运算符优先级表......只是没有发现那个地方:(
  • @fritzone 只有真正的 C 书呆子才知道该语言中每个运算符的运算符优先级 :) 这就是为什么总是鼓励将额外的括号作为良好的编程习惯的原因。即使 you 知道某些特定运算符的运算符优先级,阅读您的代码的人也可能不知道。甚至 C 语言的创建者recognized early on 认为 == 的运算符优先级也会造成麻烦。这是一种 C 的设计缺陷。
【解决方案2】:

For historical reasons,按位运算符有一个奇怪的operator precedence

您必须使用括号来强制执行正确的顺序:

while (c2 != (246^252))

事实上,我强烈建议您在使用这些运算符时始终使用括号。

这是一个显示差异的最小示例:

cout << (1 == 1 ^ 2) << " " << (1 == (1 ^ 2)); 
// 3 0

【讨论】:

  • 我想看看那些历史原因:)
  • 我只是想找到一篇好文章.. 基本上,最初按位运算符用于逻辑运算符,而实际的逻辑运算符是后来添加到语言中的,但到那时他们不会想要修复优先级 - 太多代码依赖于优先级顺序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-10-23
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多