链条抽出和插入,支架

Chaining Extraction and Insertion, bracketing

本文关键字:插入 支架      更新时间:2023-10-16

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

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

那么这里发生了什么?

您在这里的困惑是可以理解的!问题在于两个C++运算符<<>>的性质。在语言从C进化的早期,这些仅被用作所谓的"位移位"运算符,其中<<将把给定位数的整数值向左移位,>>将把位向右移位。因此,给定16位整数value2,其二进制表示为:

0000000000000010

表达式value << 2将整数中的所有位向左移位2位;任何移位超过"顶部"(位#15)的位都将丢失,右侧创建的"间隙"将用零填充,给出:

0000000000001000

其是数字CCD_ 10的二进制表示。

表达式CCD_ 11将所有比特向右移位2位;任何移位到"底部"(位#0)之外的位都将丢失,右侧的间隙将用零填充。因此,在您的情况下,唯一的1位丢失(从末尾掉下来),并且整个value最终为零。

现在,当C++概念出现时,需要运算符符号来输入和输出这些流(无论是字符串流还是文件,如代码中的cout)。选择运算符<<>>是因为它们"看起来"像它们实际在做的事情(箭头状的运动指示器)。幸运的是,C++语言允许为特定类型的变量重新定义任何运算符(称为"运算符重载"),如果您查看<iostream>标准标头,您将在ostream类的定义/声明中看到类似的内容:

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

这种"运算符重载"在标准库的源代码中被编码为将val的格式化版本写入由给定ostream对象(如cout)表示的文件。

请随时要求进一步澄清和/或解释。

PS:作为一个练习/思想挑衅者:如果从你的两行代码中删除括号,会发生什么?

PPS:关于使用移位运算符乘以或除以2的幂:当可能发生符号变化时,这是懒惰的,并且具有潜在的危险性;尤其是负数!参见cppreference.com(粗体字):

对于负a,a<lt;b是未定义

对于无符号的a和有符号且非负的a,a>>b的值是a/2^b的整数部分。

对于负a,a>>b的值是实现定义的(在大多数实现中,这会执行算术右移,因此结果保持为负)。

简单回答:>>是右移的位运算符。

长话短说:计算机中的数字通常以二进制形式存储,当你没有10,只有2位数字时:0和1。在这样的数字系统中,0是0,1是1,但2是10,因为第一个数字溢出(1后面没有数字),3是11,4是100等等。

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

其中有一些:

  • 位和&,后者将数字的每个位解释为一个单独的布尔:
00000110
&
00000101
=
00000100

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

  • 位或|,这是操作数的独立位的||运算:
00000110
&
00000101
=
00000111

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

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

因此最初CCD_ 30和CCD_。但在C++中,您有另一个称为运算符重载的特性,它允许您为特定类型重新定义某些运算符的行为。这方面的一些例子是operator +字符串,它允许您使用+来"添加"像这样的字符串:

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

字符串不是数字,但您仍然可以使用+来"添加"(或连接)它们,因为有人已经为+定义了这样的重载。

<<>>也发生了同样的情况:它们只是被定义为在分别与coutcin对象一起使用时被调用的重载移位运算符。

进一步研究的一些链接:

  • https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/
  • https://www.tutorialspoint.com/cplusplus/cpp_operators.htm
  • https://www.geeksforgeeks.org/operator-overloading-c/
  • https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

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

(<<)(左移)取两个数字,左移第一个操作数的位,第二个操作数决定要移位的位数。或者换句话说,用整数"y"左移整数"x"相当于x乘以2^y(2的幂为y)。

例如-

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

(>>)(右移)取两个数字,对第一个操作数的位进行右移,第二个操作数决定要移位的位数。类似地,右移(x>>y)相当于x除以2^y。

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