关闭

cout输出流的执行顺序

标签: C++cout
285人阅读 评论(0) 收藏 举报
分类:

下面是IBM的一道笔试题

#include <iostream> 
using namespace std; 

int fun( ) 
{ 
cout << "f" ; 
return 1; 
} 
int main() 
{ 

int i = 1; 
// cout << i++ << i++ << i++ << endl; 
cout << "m" << fun() << fun() << fun() << endl; 
return 1; 
} 

输出fffm111
问题:cout这种连接写法的输出的执行顺序是啥呢?

cout<<"m"<<fun1()<<fun2()<<fun3()<<endl;
<<运算是左结合的。
必然先求cout<<”m”的值,值仍然是cout
然后试图求cout<< fun1()的值,这必须先求出fun1()的值。整个表达式的值仍然是cout
然后试图求cout<< fun2()的值,这必须先求出fun2()的值。整个表达式的值仍然是cout
然后试图求cout<< fun3()的值,这必须先求出fun3()的值。整个表达式的值仍然是cout
最后是cout<< endl的值,值是cout
整个表达式语句以分号结尾
注意:问题就在这里:“这必须先求出fun1()的值”,“这必须先求出fun2()的值”,“这必须先求出fun3()的值”,这3句。这是计算<<运算的前提。只要分别在计算cout<< fun1(),cout<< fun2(),cout<< fun3(),之前完成就可以了。
因此,具体是先计算fun1()的值,还是先计算fun2()的值,还是先计算fun3()的值,还是先计算cout<<”m”的值,都不影响表达式的值。
问题就在这里:
这是个<<表达式。<<本来是位运算,但是这里cout却是来利用运算的“副作用”。
所谓副作用,就是计算一个表达式的时候,除了得到它的值以外,对环境产生的影响都是副作用。
比如:

int a=1,b=2,c=3,d; d=a<<b:
这一步,a<

int foo(int a, int b) { return a+b; } 
int bar(int a, int b) { return a-b; } 
int a=1,b=2,c=3,d; 
d=foo(a,b)+bar(b,d); 

这里,foo()和bar()都没有副作用。因此,这个表达式,不论是先计算foo(a,b)的值,还是先计算bar(b,c)的值,都不会影响计算的结果。
但是,如果是这个例子:

int foo(int* a) { (*a)++; return *a;} 
int bar(int* a) { (*a)--; return *a;} 
int a=5,b; 
b=foo(&a)+bar(&a); 

这个表达式,foo()和bar()都有副作用,所以,先计算foo(&a)还是先计算bar(&a),将直接影响到b的值。
假如先计算foo,再计算bar。
首先,a=5
计算foo(&a),a变成6,foo(&a)的值是6
计算bar(&a),a变成5,bar(&a)的值是5
这样,b=6+5=11
假如先计算bar,再计算foo。
首先,a=5
计算bar(&a),a变成4,foo(&a)的值是4
计算foo(&a),a变成5,bar(&a)的值是5
这样,b=5+4=9
这就造成了计算结果不一致。
===
那。。。怎么办
一般来说,编c/c++程序有一个纪律:一个语句中不要有两个表达式有副作用。
典型的这类行为包括:b=(a++)+(a++)+(a++);
这是典型的违反这条纪律的行为。每个a++都有副作用(改变a的值)。整个表达式的值跟求值顺序直接相连。
还有就是

char* fun() { cout<<"q"; return ""; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; 

每个fun()都有副作用(向屏幕上显示字符)。因此效果直接与求值顺序相关。(而整个表达式的值我们根本就不关心。虽然我知道,值就是cout)。
======

在c/c++中,求值顺序是怎么样的?

不知道。

C/C++的规范中,求值顺序是不规定的。这是为了给编译器以优化的空间。

比如:

b=(a+2)+(a+2);,那么如果只计算一次a+2的值,而不是两次,那么计算量会大大降低。

因此,

不要在C语言里面做这种事情:

char* fun() { cout<<"q"; return ""; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; 

要这样:

char* fun() { return "q"; } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这样更好:

string fun() { return string("q"); } 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这样就更好了:

string f="q"; // 隐式转换 
cout<<"m"<<fun()<<fun()<<fun()<<endl; // 输出的一定是 "mqqq\n" 

这应该只是个测验。我相信IBM的软件工程师们不会编出这种垃圾代码的。

代码稍微修改了下

#include <iostream> 

using namespace std; 

int fun(int i) 
{ 
    cout << "f"<<i; 
    return i; 
} 
int main() 
{ 

    int i = 1; 
    cout << i++ << i++ << i++ << endl; 
    cout << "m" << fun(1) << fun(2) << fun(3) << endl; 
    cin.get(); 
    return 1; 
} 

输出结果:
321
f3f2f1m123

如果只针对题来说的话,实际是这样的
cout<<”m”<

0
0
查看评论

C++输出流cout的执行顺序问题

首先看一个例子: int fun1() {  cout  return 1; } int fun2() {  cout  return 2; } int main() {  cout " &...
  • gao1440156051
  • gao1440156051
  • 2016-05-06 15:30
  • 723

C++中的cout以及输出流运算符

Cout详细介绍   C++编程语言互换流中的标准输出流,需要iostream.h支持。读为 "c out"。 目录 使用范例 案例分析 技巧应用 cout控制符 C++的iostream家族 VS C的printf/scanf家...
  • qq1623267754
  • qq1623267754
  • 2014-06-24 21:51
  • 1066

关于cout中连续i++的执行顺序

[C++]关于i++和++i的学习 MoaKap 今天在论坛上无意中看到有人问关于i++和++i的问题,感觉自己也不怎么熟悉,就仔细看了一下。感觉有位大侠的回复相当不错,很有特色,把问题讲得很明白,受教了。 这里摘录一下,学习学习! ---------------------...
  • seumonkey
  • seumonkey
  • 2014-02-26 10:50
  • 1520

关于C++输出流cout的执行顺序问题

首先看一个例子: int fun1() {  cout  return 1; } int fun2() {  cout  return 2; } int main() {  cout " &...
  • qq_22335577
  • qq_22335577
  • 2014-10-23 11:47
  • 333

cout标准输出流常用控制格式

使用这些格式需要声明包含 long flags( ) const 返回当前的格式标志。  long flays(long newflag) 设置格式标志为newflag,返回旧的格式标志。  long setf(long bits) 设置指定的格式标志位,返回旧的格式标...
  • snail0428
  • snail0428
  • 2016-07-31 12:59
  • 924

cout输出中多个表达式的先后执行顺序与输出顺序

#include #include #include using namespace std; int main() { vector svec; string word; cout << "Enter strings!(Ctr+Z to the en...
  • xuexiacm
  • xuexiacm
  • 2012-10-24 19:50
  • 2380

cout输出流

最开始接触到这个函数不知道是什么意思,在一个程序中见到,将其注释掉发现也没有丝毫影响,但是笔者认为一定是有其特殊的含义的,所以还是来做个总结,当做学习笔记了。         cout.precision()其实是输出流cout的一个格式控制函数,也就是在i...
  • jiangchao98
  • jiangchao98
  • 2017-07-10 11:44
  • 34

C++ cout执行顺序

C++ cout执行顺序 问题描述是这样的:如果在cout中调用函数,同时这个函数中包含输出语句,那么会先输出哪一句? 仔细一看,突然发现对C++的内容遗忘了,确实一下子看不出来输出的先后问题。 实现如下: 1 int max(int x, int y) 2 3 { 4 5 int ...
  • renhanlinbsl
  • renhanlinbsl
  • 2016-08-15 11:57
  • 397

cout的输出流顺序

C++中输入、输出用的是cin、cout,对应的有输入输出缓冲区,cin、cout都是对缓冲区中的数据进行操作,那么看下面代码:#include <iostream> using namespace std; int hello1(); int hello2(); int main() ...
  • weixin_36888577
  • weixin_36888577
  • 2017-09-27 21:39
  • 105

c++输出缓冲区刷新

在c++中,io操作都是有io对象来实现的,每个io对象又管理一个缓冲区,用于存储程序读写的数据。 只有缓冲区被刷新的时候缓冲区中的内容才会写入真实的文件或输出设备上。 那么,什么情况下会刷新输出缓冲区呢,有如下五种情况: 1.程序正常结束。作为main返回工作的一部分,将清空所有...
  • hishyboy
  • hishyboy
  • 2014-09-28 21:38
  • 1935
    最新评论