C++輸入和輸出
在C++里std::cin、std::cout、std::cerr和std::endl分別是標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤輸出和刷新緩沖區(qū)并換行,它們都在命名空間std中,那么它們真實(shí)面目是什么?我們先來(lái)看一段代碼:
#include 《iostream》 int main() { std::cout 《《 “Hello World!” 《《 std::endl; std::cerr 《《 “error” 《《 std::endl; return 0; }
這段代碼很簡(jiǎn)單,就是輸出“Hello world!”和“error”,那么這段代碼的底層原理是?我們先來(lái)看一下std::cout在標(biāo)準(zhǔn)庫(kù)中的定義:
#ifndef _LIBCPP_HAS_NO_STDOUT extern _LIBCPP_FUNC_VIS ostream cout; extern _LIBCPP_FUNC_VIS wostream wcout; #endif 。。.。。. typedef basic_streambuf《char》 streambuf; typedef basic_istream《char》 istream; typedef basic_ostream《char》 ostream; typedef basic_iostream《char》 iostream;
。。.。。. template 《class _CharT, class _Traits》 class _LIBCPP_TEMPLATE_VIS basic_ostream : virtual public basic_ios《_CharT, _Traits》 { 。。.。。. };
從以上代碼我們可以看出std::cout是一個(gè)類(lèi)basic_stream《char》的一個(gè)實(shí)例,那么很容易我們就能想到《《很有可能是類(lèi)basic_stream《char》的一個(gè)成員函數(shù),繼續(xù)追蹤下去,看看《《到底是啥。在類(lèi)模板basic_stream中我們找到成員函數(shù)聲明如下:
basic_ostream& operator《《(bool __n); basic_ostream& operator《《(short __n);
basic_ostream& operator《《(unsigned short __n); basic_ostream& operator《《(int __n);
basic_ostream& operator《《(unsigned int __n); basic_ostream& operator《《(long __n);
basic_ostream& operator《《(unsigned long __n); basic_ostream& operator《《(long long __n);
basic_ostream& operator《《(unsigned long long __n); basic_ostream& operator《《(float __f);
basic_ostream& operator《《(double __f); basic_ostream& operator《《(long double __f); basic_ostream& operator《《(const void* __p); basic_ostream& operator《《(basic_streambuf《char_type, traits_type》* __sb);
充分證實(shí)了我們猜想,《《其實(shí)是成員函數(shù)operator《《并且返回值是basic_ostream&,到這里我們就可以看出std::cout 《《 “Hello World!”其實(shí)是basic_ostream實(shí)例變量cout調(diào)用成員函數(shù)operator《《輸出字符串“Hello World!”并返回basic_ostream&。
那么std::endl是不是某個(gè)類(lèi)的實(shí)例呢?我們看看std::endl在標(biāo)準(zhǔn)庫(kù)的定義:
template 《class _CharT, class _Traits》 inline _LIBCPP_INLINE_VISIBILITY basic_ostream《_CharT, _Traits》& endl(basic_ostream《_CharT, _Traits》& __os) { __os.put(__os.widen(‘ ’)); __os.flush(); return __os; }
從代碼里可以看出,std::endl其實(shí)是一個(gè)函數(shù)模板,調(diào)用該函數(shù)會(huì)將一個(gè)換行符“ ”放入緩沖區(qū),并刷新緩沖區(qū),最后返回basic_ostream&。到這里我們終于明白std::cout 《《 “Hello World!” 《《 std::endl;的含義了,basic_ostream實(shí)例變量cout調(diào)用成員函數(shù)operator《《輸出字符串“Hello World!”,返回basic_ostream&并繼續(xù)調(diào)用成員函數(shù)operator《《輸出換行符并刷新輸出緩沖區(qū)。
現(xiàn)在我們很容易想到std::cerr和std::cout應(yīng)該差不多,區(qū)別則是std::cerr是標(biāo)準(zhǔn)錯(cuò)誤輸出,將信息輸出到標(biāo)準(zhǔn)錯(cuò)誤流。std::cerr定義如下:
extern _LIBCPP_FUNC_VIS ostream cerr; extern _LIBCPP_FUNC_VIS wostream wcerr; extern _LIBCPP_FUNC_VIS ostream clog; extern _LIBCPP_FUNC_VIS wostream wclog;
最后我們看看std::cin到底是什么玩意,先來(lái)看下下面這段代碼:
#include 《iostream》 int main() { std::string name; std::cin 》》 name; return 0; }
代碼很簡(jiǎn)單,就是想通過(guò)標(biāo)準(zhǔn)輸入輸入名字,并保存在變量name中。有了上面的經(jīng)驗(yàn),我們很容易想到std::cin應(yīng)該是某個(gè)類(lèi)的實(shí)例變量,而》》則是類(lèi)的成員函數(shù)。std::cin的定義如下:
#ifndef _LIBCPP_HAS_NO_STDIN extern _LIBCPP_FUNC_VIS istream cin; extern _LIBCPP_FUNC_VIS wistream wcin; #endif 。。.。。. typedef basic_streambuf《char》
streambuf; typedef basic_istream《char》 istream; typedef basic_ostream《char》 ostream; typedef basic_iostream《char》 iostream;
。。.。。. template 《class _CharT, class _Traits》 class _LIBCPP_TEMPLATE_VIS basic_istream : virtual public basic_ios《_CharT, _Traits》 { 。。.。。. };
從代碼中可以看出std::cin是類(lèi)basic_istream《char》的實(shí)例變量,且basic_istream是類(lèi)模板。下面我們看看》》在basic_istream中聲明:
basic_istream& operator》》(basic_streambuf《char_type, traits_type》* __sb);
basic_istream& operator》》(bool& __n); basic_istream& operator》》(short& __n);
basic_istream& operator》》(unsigned short& __n); basic_istream& operator》》(int& __n);
basic_istream& operator》》(unsigned int& __n); basic_istream& operator》》(long& __n);
basic_istream& operator》》(unsigned long& __n); basic_istream& operator》》(long long& __n);
basic_istream& operator》》(unsigned long long& __n); basic_istream& operator》》(float& __f);
basic_istream& operator》》(double& __f); basic_istream& operator》》(long double& __f);
basic_istream& operator》》(void*& __p);
不出我們所料》》確實(shí)是成員函數(shù)operator》》并返回basic_istream&,那么這段代碼std::cin》》name就很容易理解了,basic_istream《char》類(lèi)實(shí)例變量cin調(diào)用成員函數(shù)operator》》從標(biāo)準(zhǔn)輸入輸入數(shù)據(jù),并保存在變量name中。到這里std::cout、std::cin、std::cerr和std::endl的含義終于真相大白了!
責(zé)任編輯:haq
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4308瀏覽量
62434 -
C++
+關(guān)注
關(guān)注
22文章
2104瀏覽量
73500
原文標(biāo)題:std::cin、std::cout、std::cerr和std::endl在C++里的真實(shí)面目
文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論