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,搞清楚了還是挺開心的^^

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM