为什么使用cout和cin进行按位移动(<<和>>)?

问题真的在标题中; 我确定有一些合乎逻辑的东西,但是现在我很难过了!

根据C ++devise和演化的第 8.3.1节:

Doug McIlroy通过类比Unix shell中的I / Oredirect操作符(>,>>,|等)提出了提供输出运算符而不是命名输出函数的思想,

[…]

一些运算符被认为是input和输出操作:“赋值运算符是input和输出的候选对象,但它的方法是错误的,那就是cout=a=b将被解释为cout=(a=b)大多数人似乎更喜欢input操作符与输出操作符不同,操作符<>被尝试过,但是“小于”和“大于”的含义如此牢固地植入人们的脑海中,新的I / O语句实际上是不可读的(对<<和>>而言似乎并不是这种情况),除此之外,大多数键盘上的“<”就在“,”之上,人们正在写这样的expression式:

 cout < x , y, z; 

为此提供良好的错误信息并不容易。“

也许是因为它看起来类似于Unix追加操作,因为你本质上是附加到input/输出stream?

例如

产量

echo "foo" >> bar

input

sendmail -f test@domain.com << myemail.txt

(偷取来自Zac Howland的input示例)

从“C ++编程语言”。 Stroustrup(语言作者)的话:

将运算符<<重载为<< '”意味着更好的符号,并让程序员在一个语句中输出一系列对象。

但为什么? 发明一个新的词汇标记是不可能的。 赋值运算符是input和输出的候选者,但大多数人似乎更喜欢使用不同的运算符来input和输出。 此外,=错误的方式; 即cout = a = b意味着cout =(a = b)而不是(cout = a)= b。 我尝试过操作符<> ,但是“小于”和“大于”的意思如此牢固地植入人们的脑海中,新的I / O语句实际上是无法读取的。

>><<只是运营商,你可以实现你自己的>><<你的课程。

我想“有人”select它们是因为:a)它们与shell文件操作类似,b)重用现有的操作符,因为不需要创build新的操作符

所以你还记得,如果你认为cin是一个键盘和cout作为显示器,你input的内容就进入了variables

 cin>>var; 

或者你的variables的内容进入屏幕

 cout<<var; 

因为他们或多或less有一个合理的优先,看起来不错。 在C ++中,你不能创build新的操作符或改变它们的优先级或分组规则,你只能重载现有的操作符并改变它们的实际操作。

<<>>的select有一些不幸的副作用,因为它在某种程度上推动了输出将按照顺序完成的想法。 虽然对于实际的输出来说这是真实的,但是由于巧妙的链接技巧,所涉及的计算却是错误的,这通常是令人惊讶的。

要更具体的写作

 std::cout << foo() << bar() << std::eol; 

并不意味着foo会在之前被调用。

它们不是按位运算符,在这种情况下它们被称为插入和提取操作符。

http://www.cplusplus.com/doc/tutorial/basic_io/

这些仅用于视觉解释。 如果你研究开发自己的stream和运算符重载,那么你可以看到,你甚至可以使用+input和 – 输出:)

这个答案不令人满意,但却是正确的:它们不是按位运算符。

操作符的含义由其左侧显示的数据types决定。 在cin和cout(以及其他streamtypes)的情况下,<<和>>操作符将值移入和移出stream。 在左操作数是整数的情况下,操作是您从C中已经知道的按位操作。

运营商的含义并不固定,尽pipe它的优先级是。

主要是因为他们的相关性。 插入和提取操作符从左到右依次关联

 std::cout << "Hello" << ' ' << 4 << 2; 

按照你的预期进行评估:首先用"Hello" ,然后用' ' ,最后用42 。 当然,加法运算operator+也是从左到右。 但是这个算子和其他从左到右的关联性已经有了不同的含义。

Bjarneselect了他们的实际优先权,联想性和助记价值。

优先级并不完美,比如布尔型和位级操作符都很麻烦。

但是相当好。

 cout << "Output sentence"; // prints Output sentence on screen cout << 120; // prints number 120 on screen cout << x; // prints the content of x on screen 

<<运算符将之后的数据插入到它之前的数据stream中。 在上面的例子中,它将常量stringOutput句子,数字常量120和variablesx插入到标准输出streamcout中。

标准input设备通常是键盘。 在C ++中处理标准input是通过在cinstream上应用重载操作符(>>)来完成的。 操作员必须跟随将存储将要从stream中提取的数据的variables。 例如:

 int age; cin >> age; 

插入运算符>><<分别与inputstream和输出stream一起使用,因为inputstream意味着数据stream入您的程序,输出stream意味着数据stream出您的程序。 由于这些插入运算符看起来像定向运算符(显示数据stream的方向),因此select“inputstream”和<<输出stream”。

看看代码的一部分…

 int Num1; cin >> Num1; 

在这里,如果你仔细观察>>正在显示数据stream到variables(在程序中声明),这意味着数据stream到程序,这是inputstream(这里是cin )的工作。

同样跟cout

 int Num2 = 5; cout << Num2; 

这里<<显示数据stream出程序(因为Num2是程序的一部分),这是输出stream的工作。

我希望这一切对你有意义。

我假设你知道C ++允许运算符重载。 一般来说,只有在语义是完全可转换的时候才重载操作符(例如,为了向量类添加两个向量而重载)。 我认为你的问题是指为什么要使用移位操作符,为iostream重载它们,并赋予它们与原来目的完全不同的含义。 之所以能做到这一点,是因为bitshift操作与iostream的做法相去甚远,没有人会认为<<或>>在iostream上做一个移位操作。 而且使用方便的原因还在于它们的sorting是先评估左边的操作数,然后是右边的操作数,然后进行操作。 这适合于当您使用操作员从iostream追加或提取内容时想要发生的情况。

但是,对于原来的问题,为什么呢? 我真的不知道,在我看来,“和”很容易理解为从一个实体获取信息并将其放在另一个实体中。 为什么这个原因需要比这更复杂呢? 使用它们看起来是明智的,因为它们的含义是显而易见的。你能问一个操作员什么更好?