複製鏈接
請複製以下鏈接發送給好友

cout

鎖定
cout 用於在計算機屏幕上顯示信息,是C++中iostream 類型的對象,C++的輸出是用“流”(stream)的方式實現的,流運算符的定義等信息是存放在C++的輸入輸出流庫中的,因此如果在程序中使用cout和流運算符,就必須使用預處理命令把頭文件stream包含到本文件中,即庫,該庫定義的名字都在命名空間 std 中,所以 cout 全稱是 std::cout 。 [1] 
中文名
cout
外文名
cout
類    型
std::ostream
應    用
cout
頭文件
iostream

cout簡介

圖示 圖示
輸入和輸出並不是C++語言中的正式組成成分。C和C++本身都沒有為輸入和輸出提供專門的語句結構。輸入輸出不是由C++本身定義的,而是在編譯系統提供的I/O庫中定義的。
C++的輸出和輸入是用“流”(stream)的方式實現的。圖示通過流進行輸入輸出的過程。
有關流對象cin、cout和流運算符的定義等信息是存放在C++的輸入輸出流庫中的,因此如果在程序中使用cin、cout和流運算符,就必須使用預處理命令把頭文件stream包含到本文件中:
#include <iostream>
儘管cin和cout不是C++本身提供的語句,但是在不致混淆的情況下,為了敍述方便,常常把由cin和流提取運算符“>>”實現輸入的語句稱為輸入語句或cin語句,把由cout和流插入運算符“<<”實現輸出的語句稱為輸出語句或cout語句。根據C++的語法,凡是能實現某種操作而且最後以分號結束的都是語句。 [2] 

cout基本操作

cout語句的一般格式為:
cout<<表達式1<<表達式2<<……<<表達式n;
在定義流對象時,系統會在內存中開闢一段緩衝區,用來暫存輸入輸出流的數據。在執行cout語句時,先把插入的數據順序存放在輸出緩衝區中,直到輸出緩衝區滿或遇到cout語句中的endl(或'\n',ends,flush)為止,此時將緩衝區中已有的數據一起輸出,並清空緩衝區。輸出流中的數據在系統默認的設備(一般為顯示器)輸出。 [3] 
一個cout語句可以分寫成若干行。如:
cout<<"This is a simple C++ program."<<endl;
可以寫成
cout<<"This is " //注意行末尾無分號
<<"a C++ "
<<"program."
<<endl; //語句最後有分號
也可寫成多個cout語句,即
cout<<"This is "; //語句末尾有分號
cout <<"a C++ ";
cout <<"program.";
cout<<endl;
以上3種情況的輸出均為:
This is a simple C++ program.
注意:
不能用一個插入運算符“<<”插入多個輸出項,如:
cout<<a,b,c; //錯誤,不能一次插入多項
cout<<a+b+c; //正確,這是一個表達式,作為一項
在用cout輸出時,用户不必通知計算機按何種類型輸出,系統會自動判別輸出數據的類型,使輸出的數據按相應的類型輸出。如已定義a為int型,b為float型,c為char型,則:
cout<<a<<' '<<b<<' '<<c<<endl;
會以下面的形式輸出:
4 345.789 a

cout使用範例

#include<iostream>
using namespace std;//此句也可以在main函數體中出現。
int main()
{
    int a;
    cout << "請輸入一個數字,按回車結束" << endl;
    cin >> a;
    cout << a << endl;
    return 0;
}
//用户輸入的數字由cin保存於變量a中,並通過cout輸出。
#include<iostream>
using namespace std;
int main()
{
    cout << "Hello,World!" << endl;
    return 0;
}//HelloWorld示例

cout案例分析

請看HelloWorld!的等效版本:
#include<iostream>
using namespace std;
int main()
{

    cout.operator<<("Hello,World!");
    cout.operator<<(endl);
    return 0;
}
cout是一個ostream類的對象,它有一個成員運算符函數operator<<,每次調用的時候就會向輸出設備(一般就是屏幕啦)輸出數據。
問題:為什麼函數operator<<能夠接受不同類型的數據,如整型浮點型、字符串甚至指針
運算符函數與一般函數基本無異,可以任意重載。標準庫的設計者們早已經為用户定製了iostream::operator<<對於各種C++基本數據類型的重載版本,這才使得我們這些初學者們一上來就享受到cout<<"Hello,World!"<<endl;。
cout.operator<<("Hello,World!").operator<<(endl);
問題:為什麼可以連續寫多個?
請見如下的定義:
ostream& std::cout.operator<<();
注意前面的ostream&表示返回對象的引用,也就是可以繼續cout了。
對於cin,則是istream流類的對象,其重載了>>運算符,用法與cout大致相同。

cout技巧應用

把設計的cout對象命名的myout,myout對象所屬的類為MyOutstream。要做的就是為MyOutstream類重載一系列不同類型的operator<<運算符函數,這裏僅實現了對整型(int)與字符串型(char*)的重載。為了表示與iostream斷絕關係,不再用頭文件iostream,而使用古老的stdio中的printf函數進行輸出,程序很簡單,包括完整的main函數,均列如下:
#include <cstdio>   
/*
在C和一些古老的C++中是#include<stdio.h>,
新標準為了使標準庫的頭文件與用户頭文件區別開,
均推薦使用不用擴展名的版本,
對於原有C庫,
不用擴展名時頭文件名前面要加c。
*/
class MyOutstream{
    public:
    const MyOutstream& operator << (int value)const;//對整型變量的重載
    const MyOutstream& operator << (char* str)const;//對字符串型的重載
};
const MyOutstream& MyOutstream::operator <<(int value)const{
    printf("%d",value);
    return* this;//注意這個返回……
}
const MyOutstream& MyOutstream::operator <<(char* str)const{
    printf("%s",str);
    return* this;//同樣,這裏也留意一下……
}
MyOutstream myout;//隨時隨地為我們服務的全局對象myout
int main(){
    int a=2003;
    char* myStr="Hello,World!";
    myout << myStr << "\n";
    return 0;
}

定義的myout已經初具形態,可以工作了。程序中的註釋指出兩處要特別注意的:即是operator<<函數執行完畢之後,返回一個它本身的引用,輸出已經完成,為何還要多此一舉?
還記得那個有點奇異的cout.operator<<("Hello,World!").operator<<(endl)麼?它能實現意味着我們可以連着書寫
cout<<"Hello,World!"<<endl;
而不是
cout<<"Hello,World!";

cout<<endl;
為何它可以這樣連起來寫?
分析一下:按執行順序,系統首先調用cout.operator<<("Hello,World!"),然後cout.operator<<會返回它本身,就是説在函數的最後一行會出現類似於return *this這樣的語句,因此cout.operator<<("Hello,World!")的調用結果就返回了cout,接着它後面又緊跟着.operator<<(endl),這相當於cout.operator<<(endl)——於是又會進行下一個輸出,如果往下還有很多<<算符。 [2] 

coutcout控制符

要使用下面的控制符,需要在相應的源文件中包含頭文件“iomanip”,也就是添加如下代碼:
#include <iomanip>
控制符
描 述
dec
置基數為10,後由十進制輸出(系統默認形式)
hex
置基數為16,後由十六進制輸出
oct
置基數為8,後由八進制輸出
setfill(c)
設填充字符為c
setprecision(n)
設置實數的精度為n位
setw(n)
域寬為n個字符
setiosflags(ios::fixed)
固定的浮點顯示
setiosflags(ios::scientific)
指數表示
setiosflags(ios::left)
setiosflags(ios::right)
setiosflags(ios::skipws)
忽略前導空白
setiosflags(ios::uppercase)
16進制數大寫輸出
setiosflags(ios::lowercase)
16進制數小寫輸出
其中:setw設置域寬,使用一次就得設置一次。其他的函數,設置一次永久有效。 [1] 

coutcout的相關信息

1 cout的類型是 iostream
2 ostream使用了單例模式,
保護的構造函數,不能在類外創建另一個對象(用 ostream os 測試)
拷貝構造私有,不能通過已有對象,構造新對象(用 ostream os(cout) 測試)
拷貝賦值私有,(用 cout=cout 測試)
3 cout在命名空間std中,使用前需要using namespace std,或者std::cout
4 可以使用引用,或指針指向這個對象,意思想説,想用ostream 做一個函數的形式參數,就必須使用引用或指針。因為實參肯定是cout,且只能有這一個對象。
5 cout<<對象; 對象的類型用OO表示,如想用cout打印一個對象,即cout<<對象,可使用如下程序
friend ostream& operator<< (ostream& os,
const OO& c) {//為什麼必須使用友元
return os << c.成員1 <<" : "<<c.成員2;
}

cout運算符重載

用法:把成員函數/友元函數的名字改為 operator運算符 就行了
例如:
class Obj{
public:
void operator--(int s){
cout <<s;
}
}
int main(void){ 
Obj o;
o--4;
//此時打印出一個4來
return 0;
}
參考資料
  • 1.    李普曼 . C++ Primer中文版 :電子工業出版社 ,2013.9
  • 2.    譚浩強 .C++程序設計(第3版):清華大學出版社,2015.8
  • 3.    鄭莉,董淵,何江舟.C++語言程序設計:清華大學出版社,2010.7