小议 cout << i << " " << i++ << endl

前注: 本文除了最后半句话在讨论“i++”的问题外,通篇都不关i++或++i什么事。千万别望文生义。

 

王富涛 的一个话题,问:

Code:
  1. int i = 0;  
  2. cout << i << " " << i++ << endl;  

为什么在VC6里,DEBUG 版本输出 1,0 ,而Release版本输出0,0

通常编译器,都是编译Release程序时,容易出错,因为错误的优化。不过VC的习惯是,通常RELEASE版运行的结果,更接近C++标准,私下里我们称它的优化,就是让程序更“标准化”。

这边不准备纠缠这个问题。倒是来看看,cout << i << " " << i++ << endl 是些什么东东?其它上面的代码相当于:

Code:
  1. int i=0;  
  2. ::operator << (cout.operator << (i), " ").operator << (i++).operator << (endl);  

为什么这么复杂?是因为凑巧中间夹着输出了一个字符串,此时调用的是自由函数 ::operator(ostream&, char const *);

还是有些眼晕,那么我们再简化一下:

Code:
  1. #define OUT operator<<  
  2. ::OUT(cout.OUT(i), " ").OUT(i++).OUT(endl);  
  3. #undef OUT  

为了描述方便,干脆为每个OUT编个号码:

Code:
  1. ::OUT_1(cout.OUT_2(i), " ").OUT_3(i++).OUT_4(endl);    

其中,OUT_1 是一个全局自由函数,它带两个参数,一个是流,另一个是字符串,大致原型可以写成:

Code:
  1. ostream& OUT_1(ostream& os, char const * pstr);  

而 OUT_2 ~ OUT_4, 都是同一个函数,它们是某个类的成员函数。

cout 就是那个类的一个对象(换句话说:cout一个变量)。

endl 本是一个函数 endl()……但这里用的是它的地址,这是另一个话题了。

忽略与本问题无关的,最终代码结构类似:

Code:
  1. foo_1( o.foo_2(i), " ").foo_3(i++).foo_4(endl);  

foo_1() 函数运行之后,返回一个对象,假设为a。接着,调用a的成员函数foo_3,拆解代码为:

Code:
  1. a = foo_1 (...);  
  2. a.foo_3 (i++);  
  3. //...  

但要执行foo_1,则必须求出它的第一个入参的值,所以再拆解:

Code:
  1. a_0 = o.foo_2(i);  
  2. a_1 = foo_1(a_0, " ");  
  3. a_2 = a_1.foo_3(i++);  
  4. a_3 = a_2.foo_4(endl);  

补充一句,a_x 在本例中,其实都是同一个对象。

不管如何,在执行 a_0 = o.foo_2(i)时,关后面的 a_1.foo_3(i++)什么事呢?那时候 foo_3()的宿主a_1还没有产生呢,如果有编译器非在这时让i++影响了前面的o.foo_2(i)的执行,造成后者输出一个“1”来,那能说明什么呢?我想,只能说是它错了吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南郁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值