如何在cout中使用按位移位?

时间:2019-06-01 18:21:28

标签: c++ bit-shift cout

我正在尝试执行以下操作:

#include <iostream>

int main()
{
    std::cout << 1 << 5 << std::endl;
}

我希望32(1向左移5),但我得到15。

我正在尝试使用这样的宏:

#define BIT_SHIFT(x,y) x << y
...
cout << BIT_SHIFT(1, 5) << std::endl;

发生这种情况。

为什么?我该如何解决?

3 个答案:

答案 0 :(得分:6)

只需使用括号。

#include <iostream>

int main()
{
    std::cout << (1 << 5) << std::endl;
}

std::cout << 1 << 5的意思是“推送输出流的第一个整数文字1,然后输出整数5”。但是,添加括号会更改求值顺序,并且首先对1 << 5求值,从而得到std::cout << 32 << std::endl;表达式。

答案 1 :(得分:5)

使用括号:

    std::cout << (1 << 5) << std::endl;

原因是输出ostream& operator<<(ostream&, const T&)重载链接返回值以再次调用该函数。

如果使用括号,将首先计算位移值,然后将其传递给重载的输出运算符。


  

我正在尝试在宏中使用它:...

因此,上述内容表示您的宏定义应如下所示:

#define BIT_SHIFT(x,y) ((x) << (y))

您可能想知道为什么现在要加上括号。这只是更安全地编写宏。考虑一下有人尝试使用您的宏,例如:

 cout << BIT_SHIFT(1, 5*2) << std::endl;

答案 2 :(得分:0)

  

我正在尝试执行以下操作:

#include <iostream>

int main()
{
   std::cout << 1 << 5 << std::endl;
}

您是对的。您正在尝试做类似的事情。但是,问题与宏无关(我的意思是,这也是一个问题,但稍后会再讨论)。问题在于您的目标不是您的意思。您的意思不是std::cout << 1 << 5 << std::endl;,而是std::cout << (1 << 5) << std::endl;,不同之处在于第一个分解为以下内容:

std::cout << 1;
std::cout << 5;
std::cout << std::endl;

您想要的是这样的

int i = 1 << 5;

std::cout << i;
std::cout << std::endl;

或类似的东西。

答案很简单:要么在cout语句中使用括号,要么将其放在宏中(更好的选择):

// either 
cout << (BIT_SHIFT(1, 5)) << std::endl;
// or
#define BIT_SHIFT(x,y) (x << y)
...
cout << BIT_SHIFT(1, 5) << std::endl;

而且,正如其他人所建议的,如果您愿意,您甚至可以更进一步:

#define BIT_SHIFT(x,y) ((x) << (y))
...
cout << BIT_SHIFT(1, 5) << std::endl;

那样,如果您在xy中做一些奇怪的事情,您的代码就不会中断。