链接提取和插入,包围

Chaining Extraction and Insertion, bracketing

我试图试验这些 iostream 奇怪的行为。

int value = 2;

cout << (value << 2) << endl; //output is 8
cout << (value >> 2) << endl; //output is 0

那么这里发生了什么?

在流的情况下,它们是插入和提取运算符。 否则,它们被称为左移和右移运算符。 从 Link 了解这些 但暂时让我解释一下你的输出。

(<<) (left shift) Takes two numbers, left shifts the bits of the first operand, the second operand decides the number of places to shift. Or in other words left shifting an integer “x” with an integer “y” is equivalent to multiplying x with 2^y (2 raise to power y).

例如 -

 a = 5//(00000101)
 a<<1
result is 10(00001010)>// here bit shifted by one position.

(>>) (right shift) Takes two numbers, right shifts the bits of the first operand, the second operand decides the number of places to shift.Similarly right shifting (x>>y) is equivalent to dividing x with 2^y.

a = 5;//(00000101)
The result is 00000010 which is 2
printf("b>>1 = %d\n", b>>1); 

简答:>>是右移bitwise operator

长答案: 计算机中的数字通常以二进制存储,当您没有 10,而只有 2 个数字时:0 和 1。在这样的数字系统中,您将 0 表示为 0,将 1 表示为 1,但将 2 表示为 10,因为第一个数字溢出(有1)后面没有数字,三为11,四为100等

许多编程语言提供了一些作用于数字二进制表示的操作。

其中有一些:

  • bit-and &,它将数字的每一位解释为一个单独的布尔值:
00000110
&
00000101
=
00000100

这里你只看到结果中的第三位设置为 1,因为这是前两个数字中唯一设置为 1 的位。

  • 位或|,即||操作数的单独位操作:
00000110
&
00000101
=
00000111

在这里,对于前两个数字中任何一个为 1 的任何位,您会看到结果中的 1 位。

  • 右移 >>,其中 "moves" 一个数字的所有位向右移动一些位置:
00110100 >> 2
=
00001101
  • 左移<<,与前面相同,但将位向左移动:
00000101 << 3
=
00101000

所以最初 <<>> 是位移运算符。但是在 C++ 中,您有另一个称为 operator overloading 的功能,它允许您为您的特定类型重新定义某些运算符的行为。这方面的一些例子是 operator + for strings 允许你使用 + for "adding" strings like this:

string a = "Hello";
string b = "World";
string c = a + ", " + b;

字符串不是数字,但您仍然可以将 + 用于 "adding"(或连接)它们,因为有人已经为 +.

定义了此类重载

同样的事情发生在 <<>> 上:这些只是重载的移位运算符,定义为分别在与 coutcin 对象一起使用时调用.

进一步研究的一些链接:

你在这里的困惑是可以理解的!问题在于两个 C++ 运算符 <<>> 的性质。在语言从 C 演变的早期,这些 专门 用作 so-called "bit-shift" 运算符,其中 << 会将整数中的值向左移动给定位数,而 >> 会将位向右移动。因此,对于 16 位整数 2value,其二进制表示形式为:

0000000000000010

表达式value << 2将整数中的所有位向移动2位;任何超出 'top'(第 15 位)的位都将丢失,并且在右侧创建的 'gaps' 将用零填充,给出:

0000000000001000

这是数字8的二进制表示。

表达式 value >> 2 将所有位向 右移 2 位 ;任何超出 'bottom'(位#0)的位都将丢失,右边的空位用零填充。因此,在您的情况下,唯一的 1 位丢失(从末尾掉下来),并且总体 value 最终为零。

现在,当 C++ 概念出现时,需要运算符符号来输入和输出此类流(无论是 string 流或 file 流,如代码中的 cout)。选择运算符 <<>> 是因为它们 'look' 喜欢他们实际做的事情(arrow-like 移动指标)。幸运的是,C++语言允许重定义 of any运算符用于特定类型的变量(它被称为 "operator overloading")并且,如果您查看 <iostream> 标准 header,您将在 ostream [=] 的 definition/declaration 中看到类似的内容94=]:

ostream& operator<< (int val);
//.. similar lines for types other than int

此 "operator overload" 在标准库的源代码中编码为将 val 的格式化版本写入由给定 ostream object 表示的文件(如 cout).

随时要求进一步澄清and/or解释。

PS:作为一个exercise/thought-provoker:如果从你的两行代码中删除括号,预计会发生什么?

PPS: 关于使用 bit-shift 运算符乘以或除以 powers-of-2:这是懒惰的并且可能当 change-of-sign 可能发生时很危险;特别是对于负数!参见 cppreference.com(加粗我的):

For negative a, the behavior of a << b is undefined.

For unsigned a and for signed and non-negative a, the value of a >> b is the integer part of a/2^b.

For negative a, the value of a >> b is implementation-defined (in most implementations, this performs arithmetic right shift, so that the result remains negative).