c++_cout的理解和使用

問題引入

cout << (uf.is_same_set(x, y)) ? 'Y' : 'N'<<endl;

請問大家,這條語句對嗎?(這里的uf.is_same_set(x, y)是一個自定義函數,返回bool值;所以不是問題的關鍵)==》

答案是這條語句報錯了。我再寫了以下的語句,卻能準確無誤。

 ?cout << ((uf.is_same_set(x, y)) ? 'Y' : 'N') << endl;

為什么呢? ==》

1.這是因為第一條語句中,<<的優先級會高于三目運算符,即它先返回的是 ostream&;

然后會再執行ostream?'Y':'N'部分;三目判斷返回'Y'

但是'Y' 是 char 類型,不是一個可以用 << 運算的對象。

2.cout << ((uf.is_same_set(x, y)) ? 'Y' : 'N') << endl; 這個表達式會先執行三目,返回‘Y’或者‘N’;然后變為:cout<<'Y'<<endl; 所以就沒有錯。

基于這個問題,我們今天就來聊聊cout

cout是什么?

cout 是一個全局的 輸出流對象,本質上是 ostream 類的一個實例,通過 運算符重載(operator<<,實現了類似 cout << x 這樣的打印效果。

此外還有其他流對象是:

名稱類型功能
cinistream標準輸入流
cerrostream錯誤輸出流
clogostream日志輸出流

為什么能用 << 打印?

這是 C++ 的經典設計:通過重載運算符 <<(插入運算符)來模擬輸出操作。它的原型類似于這樣:即它使重載的運算符函數;

ostream& operator<<(ostream& os, int value);
ostream& operator<<(ostream& os, const char* str);
ostream& operator<<(ostream& os, char c);
ostream& operator<<(ostream& os, double d);
ostream& operator<<(ostream& os, bool b);
// 等等,針對不同類型都做了重載

這就意味著你可以這樣使用:

cout << "Hello" << ' ' << 42 << ' ' << true;

它的底層執行順序是:

cout << "Hello" ? ? ? ? ?// 返回 ostream&<< ' ' ? ? ? ? ? ? // 繼續插入<< 42 ? ? ? ? ? ? ?// 繼續插入<< ' ' ? ? ? ? ? ? // ...<< true; ? ? ? ? ? // 一連串流式操作

因為每次 << 都返回 ostream&,所以可以鏈式調用。


輸出是怎么“流”到控制臺的?

cout 內部持有一個緩沖區(buffer),你每調用一次 <<,其實是將數據寫入這個緩沖區。只有當你:

  • 顯式使用 endl(刷新并換行);

  • 或緩沖區滿;

  • 或程序結束前清理資源;

才會真正把內容輸出到終端控制臺所以我們便能理解下面兩條語句的區別了。

cout << "hello\n"; ? ? ? // 可能只是寫進緩沖區
cout << "world" << endl; // 此時強制刷新緩沖區

endl 是什么?

endl 是一個特殊的東西,它不是字符串,而是一個 函數指針,原型是:

ostream& endl(ostream& os);

它的作用是:

  1. 向流中插入一個換行符(\n);

  2. 刷新緩沖區(flush);

所以cout << "Hello" << endl; 等價于:

cout << "Hello";
cout.put('\n');
cout.flush();

自定義類型如何支持 << 輸出?

你可以為你的類自己寫一個 << 重載,讓 cout << 對象 成為可能:

class Person {
public:string name;int age;
};
?
// 重載 <<
ostream& operator<<(ostream& os, const Person& p) {os << "Name: " << p.name << ", Age: " << p.age;return os;
}

這樣你就能這樣寫:

Person p{"麥兜", 20};
cout << p << endl;

ok,這個知識點實際上涉及到了運算符重載函數的編寫;我先說一個結論:

operator<<必須寫成全局函數(或友元函數),為什么呢?

因為 cout << p 是這樣調用的:operator<<(cout, p); // ostream 是左邊,Person 是右邊

如果你寫成:

class Person { ostream& operator<<(ostream& os); // 錯誤!只能是 p << cout 
};

這就變成了 p << cout,方向顛倒了,所以沒法實現 cout << p 的語法。

故哪些運算符建議寫成成員函數?哪些建議全局?

運算符類型推薦形式說明
=, [], (), ->成員函數這些操作符需要訪問類的內部狀態或作用于“左側對象本身”
<<, >>, +, -, ==, !=全局函數或友元函數左側不是類對象(如 cout << obj),或需要雙操作數對稱性

cout的使用技巧

  1. 運算符優先級陷阱 (如我們上面的問題)

  2. 輸出 bool 值時注意格式

cout << true << endl; ? ? ?// 輸出: 1
cout << boolalpha << true << endl; ?// 輸出: true ?

? ?3.輸出字符和整數要區

    char ch = 'A';
    int x = 65;
    cout << ch << endl; ? ? // 輸出: A
    cout << static_cast<int>(ch) << endl; ?// 輸出: 65

    4.其他格式化技巧:

    我們需要加上 頭文件: #include <iomanip>

    1) 設置小數精度 ;如上

    2) 寬度對齊 & 填充字符

    cout << setw(10) << 42 << endl; ? ? ? ? // 寬度為10,默認右對齊
    cout << setfill('*') << setw(10) << 42 << endl; ?// 輸出:********42

    3)左右對齊

    cout << left << setw(10) << 42 << endl; ? // 左對齊
    cout << right << setw(10) << 42 << endl; ?// 右對齊

    4) 輸出十六進制/八進制

    cout << hex << 255 << endl; ?// ff
    cout << oct << 255 << endl; ?// 377
    cout << dec << 255 << endl; ?// 255 (恢復十進制)

    顯示符號位(正數也帶 + )

    cout << showpos << 123 << endl; ?// +123

    再次理解

    運算符重載是指可以自定義某個類使用某個運算符的邏輯,譬如+,-,*等等。

    而<<這個運算符也是可以被重載的;例如ostream類就是重載了這個運算符 。

    cout是ostream的一個對象,它使用<<能夠將數據寫入這個緩沖區。

    實際上cout<<10是operator<<(cout, 10);的語法糖。即他本質上是調用了operator<<,并把要打印的東西(整數,浮點數,字符,字符串)作為參數。

    而這個運算符重載函數返回的是ostream&,即引用類型,則他可以實現鏈式調用;

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/bicheng/85335.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85335.shtml
    英文地址,請注明出處:http://en.pswp.cn/bicheng/85335.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    山東大學項目實訓-創新實訓-法律文書專家系統-項目報告(八)

    項目實訓博客 : 項目后端架構 , 項目的四端交互(前端 ,后端 ,模型端 ,數據庫)的開發和維護 , 項目功能總覽 作為項目的后端和前端交互功能主要開發者,我需要對項目的四端交互進行開發和維護. 總覽: 整體項目結構如圖所示: 前后端的交互: 前端封裝了request.js : 方便前端…

    12.8Java Swing 中的MVC

    在 Java Swing 中&#xff0c;MVC 模式被廣泛應用。例如&#xff0c;JTable、JList 等組件都采用了這種模式。通常&#xff1a; 模型&#xff1a;實現特定的 Swing 模型接口&#xff08;如 TableModel、ListModel&#xff09;。視圖&#xff1a;是 Swing 組件本身&#xff08;…

    DDS(Data Distribution Service)

    DDS&#xff08;Data Distribution Service&#xff09;是一種以數據為中心的發布/訂閱&#xff08;DCPS&#xff09;通信中間件協議棧標準&#xff08;由OMG組織維護&#xff09;。它專為高性能、可預測、實時、可靠的分布式系統設計&#xff0c;廣泛應用于國防、航空航天、工…

    python爬蟲關于多進程,多線程,協程的使用

    簡介&#xff1a; python其實沒有真正意義的多線程&#xff0c;因為有GIL鎖存在&#xff0c;但是python3.13去掉GIL鎖&#xff0c;有兩個版本&#xff0c;python3.13t和python3.13&#xff0c;python3.13去掉GIL鎖相當于python底層大規模改變&#xff0c;肯定會影響一些庫的使…

    java 設計模式_行為型_23狀態模式

    23.狀態模式 Java中的狀態設計模式是一種軟件設計模式&#xff0c;當對象的內部狀態更改時&#xff0c;該模式允許對象更改其行為。狀態設計模式通常用于以下情況&#xff1a;對象取決于其狀態&#xff0c;并且在運行期間必須根據其內部狀態更改其行為。狀態設計模式是許多行為…

    Flink CDC MySQL 時區相差 8 小時問題優雅解決方式

    Flink CDC MySQL 時區相差 8 小時問題解析 代碼運行環境 Flink 1.15 + FlinkCDC 2.4.0 + jdk1.8 +springboot 2.31、原因分析 Flink CDC 底層使用 Debezium 連接器來捕獲 MySQL 的數據變更,而 Debezium 在解析 MySQL 的 binlog 日志時,默認使用 UTC 時區來處理時間字段。若…

    如何在 MX Linux 上安裝 Blender CAD 軟件

    Blender 是一款免費且開源的 CAD 軟件,可用于 3D 動畫、建模、動態圖形、紋理處理、電腦游戲、UV 展開等。同時它也是一款專業的開源程序,是商業軟件(如 Maya 或 Cinema 4D)的替代品,支持導入或導出標準格式,如 OBJ、FBX、3DS、PLY 和 STL。Blender 還可以作為視頻編輯軟…

    電腦上的.ssh目錄只做什么的

    .ssh 目錄的作用和來源 系統自動創建 這個目錄是在你第一次使用SSH相關功能時自動創建的比如第一次執行 ssh 命令連接服務器時或者使用Git通過SSH協議克隆代碼時 主要用途 SSH密鑰存儲 - 存放公鑰/私鑰對已知主機記錄 - known_hosts 文件記錄你連接過的服務器指紋SSH客戶端…

    Excel大廠自動化報表實戰(互聯網金融-數據分析周報制作下)

    這是Excel大廠自動化報表實戰第四期--互聯網金融-數據分析周報制作下 數據資源已經與這篇博客捆綁&#xff0c;有需要者可以下載通過網盤分享的文件&#xff1a;2.4自動化報表-8月成交數據.xlsx&#xff0c;2.4自動化報表-8月獲客數據.csv等2個文件 鏈接: https://pan.baidu.c…

    界面組件DevExpress WPF中文教程:Grid - 節點(Nodes)概述

    DevExpress WPF擁有120個控件和庫&#xff0c;將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有著強大互動功能的XAML基礎應用程序&#xff0c;這些應用程序專注于當代客戶的需求和構建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件…

    開源統一數據庫管理平臺完全指南:私有化部署方案與技術解析

    摘要:面對MySQL、Oracle、Redis等混合數據庫環境,如何實現統一管控?本文深度評測5大開源平臺,附私有化部署方案和性能對比。 一、核心需求場景與技術選型 典型痛點: #mermaid-svg-LuCYYyJjBakpzzFH {font-family:"trebuchet ms",verdana,arial,sans-serif;font…

    hot100 -- 14.貪心算法

    1.買賣股票的最佳時機 方法&#xff1a; def MaxProfit(prices):max_pro, min_num 0, float(inf)for num in prices:if num < min_num:min_num nummax_pro max(max_pro, num - min_num)return max_pro 2.跳躍游戲 問題&#xff1a; 給你一個非負整數數組 nums &#…

    Celery+fastAPI/Flask實現高性能應用

    本文在創作過程中借助 AI 工具輔助資料整理與內容優化。圖片來源網絡。 引言 大家好&#xff0c;我是沛哥兒。 在當今的軟件開發領域&#xff0c;異步任務處理和高效的 Web 開發框架是提升應用性能和可擴展性的關鍵因素。Celery 作為一個強大的分布式任務隊列系統&#xff0c;…

    【音視頻】PJSIP庫——pjsua命令使用詳解

    1、源碼編譯 1)安裝依賴庫 sudo apt install libsrtp2-dev sudo apt install libopus-dev alsa-tools libalsaplayer-dev ffmpeg libalsa* pulseaudio-module-jack sudo apt install jackd libjack-jackd2-dev libjack-dev libsdl2-dev libv4l-dev libavcodec-dev libavde…

    Python實例題:圖片批量處理工具

    目錄 Python實例題 題目 問題描述 解題思路 關鍵代碼框架 難點分析 Python實例題 題目 圖片批量處理工具 問題描述 開發一個 Python 工具&#xff0c;實現以下功能&#xff1a; 遍歷指定文件夾下的所有圖片文件&#xff08;支持常見格式如 jpg、png、webp&#xff0…

    超圖superMap iObjects for Java的Jar使用中遇到的問題

    一、 cannot open shared object file: No such file or directory 1. 問題 2. 解決方法 &#xff08;1&#xff09;檢查有沒有配置環境變量 PATH &#xff08;2&#xff09;創建軟連接 ln -s &#xff08;3&#xff09;將主機 /usr/lib64 目錄中的libgomp.so.1 復制到 /pla…

    常見的藍牙5.0抗干擾技術和算法

    常見的藍牙5.0抗干擾技術和算法&#xff1a; 跳頻擴頻&#xff08;Frequency Hopping Spread Spectrum, FHSS&#xff09; 通過在不同的頻率通道上快速切換數據傳輸&#xff0c;減少與固定頻率干擾源的沖突。 直接序列擴頻&#xff08;Direct Sequence Spread Spectrum, DSSS&…

    牛客與Moka深化合作,升級AI面試對接,引領招聘變革

    近日&#xff0c;AI 招聘平臺牛客與國內領先的人力資源全模塊平臺 Moka 宣布完成 AI 面試產品的全新對接升級。此次升級實現了從 Moka 到牛客的一鍵互綁&#xff0c;并打通了簡歷出題、風險點提問、優勢技能挖掘等核心功能&#xff0c;為企業提供更加高效智能的面試體驗。 這一…

    Vue 3 路由跳轉全面指南(Composition API + <script setup>)

    一、前言&#xff1a;為什么要學習 Vue Router&#xff1f; 在單頁面應用(SPA)開發中&#xff0c;路由管理是核心功能之一。Vue Router 作為 Vue.js 官方推薦的路由解決方案&#xff0c;與 Vue.js 深度集成&#xff0c;提供了以下重要功能&#xff1a; 頁面無刷新跳轉&#x…

    JavaScript基礎-常用的鍵盤事件

    一、前言 在網頁開發中&#xff0c;用戶交互 是非常重要的一環。除了鼠標操作之外&#xff0c;鍵盤事件也是前端開發中最常見的交互方式之一。 JavaScript 提供了多個用于監聽和處理鍵盤輸入的事件&#xff0c;例如 keydown、keyup 和 keypress。掌握這些事件可以幫助我們實現…