链条抽出和插入,支架
Chaining Extraction and Insertion, bracketing
我试图尝试这些iostream奇怪的行为。
int value = 2;
cout << (value << 2) << endl; //output is 8
cout << (value >> 2) << endl; //output is 0
那么这里发生了什么?
您在这里的困惑是可以理解的!问题在于两个C++
运算符<<
和>>
的性质。在语言从C
进化的早期,这些仅被用作所谓的"位移位"运算符,其中<<
将把给定位数的整数值向左移位,>>
将把位向右移位。因此,给定16位整数value
的2
,其二进制表示为:
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;
字符串不是数字,但您仍然可以使用+
来"添加"(或连接)它们,因为有人已经为+
定义了这样的重载。
<<
和>>
也发生了同样的情况:它们只是被定义为在分别与cout
和cin
对象一起使用时被调用的重载移位运算符。
进一步研究的一些链接:
- 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);
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 预处理器:插入结构名称中的前一个行号
- 在未初始化映射的情况下,将值插入到映射的映射中
- 如何在c++中只将键插入到bimap的一侧
- 如何将结构插入到集合中并打印集合的成员
- C++json插入数组
- Visual Studio 2019:插入多个C++风格的单行注释
- nlohmann-json将一个数组插入到另一个数组中
- 有效地使用std::unordered_map来插入或增加键的值
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 正在插入动态数组
- 插入或删除时获取usb的dos_name
- 叮叮当当在修复时插入多个"覆盖"说明符
- 链表c++插入,所有情况都已检查,但没有任何工作
- 将重物插入std::map
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 在数字之间插入 + 或 - 符号以使其等于整数
- 在字符串中插入空格
- 链条抽出和插入,支架