c語言中define和const?在C 裡std::cin、std::cout、std::cerr和std::endl分别是标準輸入、标準輸出、标準錯誤輸出和刷新緩沖區并換行,它們都在命名空間std中,那麼它們真實面目是什麼?我們先來看一段代碼:,下面我們就來說一說關于c語言中define和const?我們一起去了解并探讨一下這個問題吧!
在C 裡std::cin、std::cout、std::cerr和std::endl分别是标準輸入、标準輸出、标準錯誤輸出和刷新緩沖區并換行,它們都在命名空間std中,那麼它們真實面目是什麼?我們先來看一段代碼:
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
std::cerr << "error" << std::endl;
return 0;
}
這段代碼很簡單,就是輸出"Hello world!"和"error",那麼這段代碼的底層原理是?我們先來看一下std::cout在标準庫中的定義:
#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是一個類basic_stream<char>的一個實例,那麼很容易我們就能想到<<很有可能是類basic_stream<char>的一個成員函數,繼續追蹤下去,看看<<到底是啥。在類模闆basic_stream中我們找到成員函數聲明如下:
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);
充分證實了我們猜想,<<其實是成員函數operator<<并且返回值是basic_ostream&,到這裡我們就可以看出std::cout << "Hello World!"其實是basic_ostream實例變量cout調用成員函數operator<<輸出字符串"Hello World!"并返回basic_ostream&。
那麼std::endl是不是某個類的實例呢?我們看看std::endl在标準庫的定義:
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{
__os.put(__os.widen('\n'));
__os.flush();
return __os;
}
從代碼裡可以看出,std::endl其實是一個函數模闆,調用該函數會将一個換行符"\n"放入緩沖區,并刷新緩沖區,最後返回basic_ostream&。到這裡我們終于明白std::cout << "Hello World!" << std::endl;的含義了,basic_ostream實例變量cout調用成員函數operator<<輸出字符串"Hello World!",返回basic_ostream&并繼續調用成員函數operator<<輸出換行符并刷新輸出緩沖區。
現在我們很容易想到std::cerr和std::cout應該差不多,區别則是std::cerr是标準錯誤輸出,将信息輸出到标準錯誤流。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到底是什麼玩意,先來看下下面這段代碼:
#include <iostream>
int main()
{
std::string name;
std::cin >> name;
return 0;
}
代碼很簡單,就是想通過标準輸入輸入名字,并保存在變量name中。有了上面的經驗,我們很容易想到std::cin應該是某個類的實例變量,而>>則是類的成員函數。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是類basic_istream<char>的實例變量,且basic_istream是類模闆。下面我們看看>>在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);
不出我們所料>>确實是成員函數operator>>并返回basic_istream&,那麼這段代碼std::cin>>name就很容易理解了,basic_istream<char>類實例變量cin調用成員函數operator>>從标準輸入輸入數據,并保存在變量name中。
到這裡std::cout、std::cin、std::cerr和std::endl的含義終于真相大白了!
往期推薦
C 11很吊的新特性!std::function
C 裡std::enable_shared_from_this是幹什麼用的?
C mutable關鍵字如何使用?
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!