cout顺序,i++和++i

先看下以下代码

#include<iostream>
using namespace std;

int x = 1;

int f1()
{
    x = 2;
    return x;
}

int f2()
{
    x = 3;
    return x;
}

int main()
{
    //Test1
    cout << x << ' ' << f1() << ' ' << f2() << endl;    //2 2 3

    //Test2
    int i = 0;
    
    cout << i++ << ' ' << i << ' ' << ++i << endl;    //1 2 2
    
    //Test3
    int s[] = {1, 2, 3};

    int *p = s;
    
    //cout << *p << ' ' << *(p++) << ' ' << *(++p) << endl;    //3 2 3

    //cout << *p++ << ' ' << *++p << ' ' << *p << endl; //2 3 3

    //cout << *p << ' ' << *++p << ' ' << *p << endl; //2 2 2

    //cout << *++p << ' ' << *p << ' ' << *++p << endl; //3 3 3

    //cout << *p++ << ' ' << *p << ' ' << *p++ << endl; //2 3 1

    //cout << *p << " " << *p++ << " " << *p << endl;//2 1 2
}
View Code

 

 

  1. 首先先明白运算符重载:
    ostream & operator <<(ostream &stream, T &t)

    返回的是一个ostream类型的引用,为什么要返回引用,先留着待会说。

  2. 然后,cout是什么,是一个ostream类的对象
  3. 接着,cout<<a;的实质是cout对象调用其成员函数operator<<(),即cout.operator<<(a),返回一个ostream类型的引用
  4. 那么cout << a << f();其实就是cout.operator<<(a).operator<<(f())。(可以把cout.operator<<(a)看成一个新的cout)
  5. 问题来了,cout是从右到左读取参数,如果参数是函数,则先执行函数体,再将返回的值压栈,否则直接将压栈,最后再将栈中的值输出来(见上述例子的第一个输出)
  6. 如果涉及i++和++i呢,问题就变得更加复杂。因为不同的编译器有不同的输出结果啊!这里选的是vs2013。这里先要明白什么是i++和++i
    T operator ++()                    //++var
    {
        var = var+1;
        return var;
    }
    T operator ++(int dummy)        //var++(dummy)
    {
        T tmp = var;
        var = var+1;
        return tmp;  
    }

    可以看到,++i比i++更有效率(少了一句T tmp=var;)

  7. 那么同样,cout是从右到左读取参数,若遇到i++,则立即将i的压栈(注意是值,而不是i的引用),再执行i+1;若遇到++i,则先执行i+1,再将i的引用压栈(而不是i的值,是引用!!!);若遇到i,则将i的引用压栈。
  8. 最后一个问题,为什么
    ostream & operator <<(ostream &stream, T &t)

    要返回一个引用类型呢?如果不返回引用类型而是返回一个ostream对象的话,那么cout << a << b这样的式子就会有问题,编译不会通过的,因为cout<<a返回了一个ostream的对象,而这个对象是一个“值”,而不是一个“变量”,它不能作为左值。(比如a = 1是正确的,而1 = 1是错误的,因为1是一个值,而不是变量,不能作为左值)。

  9. 至此,上面的代码为什么会输出这些奇怪的结果就一目了然了,值得吐槽的一点是,这些跟编译器有关,研究起来很没意思,Anyway,搞清楚了还是挺开心的^^

 

转载于:https://www.cnblogs.com/chenyg32/p/3708164.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值