【C++起飛之路】初級—— auto、范圍for循環、宏函數和內聯函數

auto、范圍for、內聯函數、宏函數和nullptr

  • 一、auto — 類型推導的魔法(C++ 11)
    • 1、auto 是什么?
    • 2、工作原理
    • 3、優勢
    • 4、限制和注意事項
  • 二、范圍for (C++11)
    • 1、基本語法
    • 2、優勢
    • 3、工作原理
    • 4、注意事項
    • 5、C++11: 范圍 for 循環的擴展:
  • 三、宏函數
    • 1、優勢
    • 2、宏函數的危險
  • 四、內聯函數
    • 1、基本概念
    • 2、工作原理
    • 3、優勢
    • 4、注意事項
    • 5、內聯函數與編譯器優化

一、auto — 類型推導的魔法(C++ 11)

C++11 引入的 auto 關鍵字在現代 C++ 編程中扮演著重要的角色。它不僅使代碼更加簡潔,還提供了更好的可讀性和靈活性

1、auto 是什么?

auto 是 C++ 中的一個關鍵字,用于實現類型推導。它允許編譯器在變量聲明時根據初始化表達式的類型自動推導變量的類型
→ 這樣,我們可以避免顯式指定變量類型,減少代碼冗余,同時保持類型安全。

typeid 可以查看對象類型,需要#include<typeinfo>
用法: typeid(c).name(),c是變量名
在這里插入圖片描述

2、工作原理

在編譯過程中,auto 關鍵字的使用會被編譯器替換為實際的類型。

編譯器會通過初始化表達式來推導變量的類型,然后將推導出的類型替換到 auto 處。這意味著 auto 并不是一個新的數據類型,而只是一種方便的聲明方式。

3、優勢

  • a. 簡潔: 使用 auto 可以省略變量類型的冗長聲明,使代碼更加簡潔。

  • b. 可讀性: auto 提供了更清晰的代碼,讀者可以更容易地理解代碼的含義,而不必深入研究類型。

  • c. 容器迭代: 在遍歷容器時,auto 的使用可以避免手動指定容器類型,從而提高可讀性和靈活性。

  • d. 跨平臺性: auto 在一些情況下可以幫助提高代碼的可移植性,因為它減少了對特定數據類型大小的依賴。

4、限制和注意事項

  • a. 必須在聲明時進行初始化: auto 變量必須在聲明時進行初始化,以便編譯器能夠推導出其類型。

  • b. 不適用于函數參數和返回值: auto 通常用于聲明變量,而不適用于函數參數和返回值的類型。

  • c. 可能導致意外推導: 對于某些表達式,auto 的推導可能與預期不符,需要小心處理。

  • d. 不適用于非靜態成員變量: auto 不適用于非靜態成員變量的聲明。

  • e.不能定義數組 :※auto arr[ ] = {1,2,2,1}; //wrong

? 數組是一種比較特殊的數據結構,其大小和元素類型都是數組類型的一部分,而不是表達式的一部分

auto 關鍵字不能直接用于定義數組,是因為數組的大小和元素類型是數組類型的一部分,而 auto 只關注初始化表達式的類型推導,無法同時推導數組的大小和元素類型。

例如,一個 int 數組和一個 double 數組的類型是不同的,即使它們的大小相同。而 auto 關鍵字在推導類型時只關注初始化表達式的類型,無法同時推導出數組的大小和元素類型。
然而,在 C++11 引入的標準中,我們可以使用 decltype 關鍵字來間接推導數組類型:
在這里插入圖片描述

  • 注意定義變量a的時候就不可以加[ ]

使用 decltype 可以將數組的類型精確地推導出來,但是仍然無法推導數組的大小

二、范圍for (C++11)

1、基本語法

范圍 for 循環是一種用于遍歷容器的現代方式,它的基本語法如下:

for (element_declaration : container) 
{// 循環體
}

在這里,element_declaration 是一個聲明,用于指定在每次迭代中存儲容器中的元素。container 則是要遍歷的容器,可以是數組、標準容器(如 vector、list、map 等)或用戶自定義的容器類型。

2、優勢

  • a. 可讀性提高: 語法上更加簡潔,將遍歷的核心邏輯更突出,減少了迭代器和索引的干擾。

  • b. 避免越界錯誤: 避免了手動管理迭代器或索引的問題,從而減少了越界錯誤和其他低級錯誤的可能性。

  • c. 自動推導元素類型: 自動推導出容器中的元素類型,無需顯式指定,減少冗余信息。

3、工作原理

范圍 for 循環實際上是使用迭代器來遍歷容器的。編譯器會在幕后自動生成迭代器的代碼,以便訪問容器中的每個元素。對于不同類型的容器,編譯器會使用適當的迭代器,因此開發者無需擔心不同容器類型的迭代器實現。

4、注意事項

  • a. 不適用于修改元素: 范圍 for 循環在遍歷容器時只能讀取元素,不能修改元素的值。如果需要修改元素,應該使用傳統的 for 循環或迭代器。chu

  • b. 自動推導類型限制: 范圍 for 循環中的元素類型是自動推導的,因此可能會受到類型推導的限制。對于需要精確類型控制的場景,可能需要使用傳統 for 循環。

  • c. for循環迭代的范圍必須是確定的:對于數組而言,第一個元素 -> 最后一個元素 即是數組的范圍;但是對于函數傳參而言,傳遞數組的時候是以指針傳過去的,無法確定范圍。

5、C++11: 范圍 for 循環的擴展:

在 C++11 以后的版本中,范圍 for 循環的功能得到了擴展。

除了遍歷容器,還可以遍歷初始化列表、數組、字符串等。甚至可以使用 auto 關鍵字來自動推導元素類型。

遍歷的原理:自動取遍歷目標的每一個元素,再放到給定的臨時變量中,自動判斷結束。
auto 會根據遍歷目標的元素類型自動推導

std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
for (auto num : numbers) 
{// ...
}

👆 就是取 numbers 的元素放到 num 中,自動判斷循環結束。(直接寫數組的類型也可以 )

三、宏函數

宏函數是 C++ 中的一種預處理技術,使用預定義的宏名稱將代碼片段替換為文本
這種替換在編譯前進行(→ 不會在運行時引入額外的開銷),不進行類型檢查或語法分析

例如,我們可以使用 #define 來定義宏函數:

#define Add(x, y) ((x) + (y)) 

但是如果寫成#define Add(x, y) (x + y) 就麻煩了,因為是“替換”而不是“調用”,x和y有可能是表達式,計算結果就有可能與期望值不符

1、優勢

  • a. 強大的代碼生成能力: 宏函數可以生成復雜的代碼片段,減少重復性工作,提高開發效率。

  • b. 參數靈活: 宏函數可以接受任意數量和類型的參數,使其在某些情況下比普通函數更靈活。

  • c. 編譯前處理: 宏函數的替換發生在編譯前,因此不會在運行時引入額外的開銷。

2、宏函數的危險

  • a. 缺乏類型安全: 宏函數的替換是文本級別的,不進行類型檢查。這可能導致意外的類型問題。

  • b. 難以調試: 宏函數的錯誤可能在編譯后才會暴露,難以追蹤和修復

  • c. 可讀性和維護性: 復雜的宏函數可能會降低代碼的可讀性和可維護性,因為它們隱藏了實際的邏輯。

隨著現代 C++ 的發展,許多宏函數的使用場景已經被更安全和可讀性更好的特性取代,比如:內聯函數可以提供類似宏函數的性能優勢,同時也會進行類型檢查,增加代碼的安全性。

四、內聯函數

內聯說明:只是向編譯器發出的一個請求,編譯器可以選擇忽略這個請求

1、基本概念

內聯函數是通過在函數聲明前加上 inline 關鍵字來定義的函數。

它告訴編譯器,在每次函數調用處將函數體直接插入,而不是傳統的函數調用-返回過程。這樣可以避免函數調用的開銷,提高程序的性能。

inline int square(int x) 
{return x * x;
}

2、工作原理

內聯函數的核心思想是 在編譯器將函數調用處的代碼直接替換為函數體,類似于代碼的復制粘貼。空間換時間的思想

這樣,避免了函數調用和返回的開銷,但也可能會增加代碼的體積。編譯器會在合適的情況下自動進行內聯,不過也可以使用 inline 關鍵字來顯式指示。

3、優勢

  • a. 減少函數調用開銷: 可以大幅減少函數調用時的開銷,特別是對于短小、需要頻繁調用的函數

  • b. 提高程序性能: 能夠在一定程度上減少函數調用的開銷,從而提高程序的執行速度。

  • c. 代碼可讀性: 將函數體直接嵌入到調用處,使代碼更加緊湊,特別是對于簡單的計算型函數。

4、注意事項

  • a. 適用范圍: 內聯函數適用于函數體簡單且函數調用頻繁的情況。對于復雜的函數體,內聯可能會導致代碼體積增大,影響緩存效率。

  • b. 編譯器決策: 編譯器會根據代碼的復雜度和上下文來決定是否內聯函數。可以使用編譯器指示來強制內聯,但也需要權衡代碼大小和性能。

  • c. 大型函數不適合內聯: 大型函數的內聯可能會導致代碼膨脹,甚至適得其反。在這種情況下,更適合使用傳統的函數調用方式。

5、內聯函數與編譯器優化

現代編譯器在優化代碼時會考慮是否將函數內聯。然而,編譯器的優化決策可能因編譯器版本、編譯選項和具體代碼而異。因此,我們應該了解編譯器的優化行為,可以使用編譯器特定的指示來控制內聯行為~~

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

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

相關文章

軟件測試基礎篇——LAMP環境搭建

LAMP 1、Linux系統的其他命令 find命令&#xff1a;在目錄下查找文件 ? 格式一&#xff1a;find 路徑 參數 文件名 ? 路徑&#xff1a;如果沒有指定路徑&#xff0c;默認是在當前目錄下 ? 參數&#xff1a;-name 根據文件名來查找&#xff0c;區分大小寫&#xff1b; -…

useState() 的使用及場景

useState是 React提供的一個Hook函數&#xff0c;用于在函數組件中添加和管理狀態。它允許你在函數組件中定義一個可變的狀態&#xff0c;并在組件的生命周期中對狀態進行更新和訪問。 使用useState可以避免使用類組件時需要定義和管理繁瑣的constructor&#xff0c;state和se…

HOT83-打家劫舍

leetcode原題鏈接&#xff1a;打家劫舍 題目描述 你是一個專業的小偷&#xff0c;計劃偷竊沿街的房屋。每間房內都藏有一定的現金&#xff0c;影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統&#xff0c;如果兩間相鄰的房屋在同一晚上被小偷闖入&#xff0c;系…

適配器模式(C++)

定義 將一個類的接口轉換成客戶希望的另一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 應用場景 在軟件系統中&#xff0c;由于應用環境的變化&#xff0c;常常需要將“一些現存的對象 ”放在新的環境中應用&#xff0c;但是新環境要求…

【Golang】一文學完 Golang 基本語法

Golang 下載 安裝包鏈接&#xff1a;https://share.weiyun.com/InsZoHHu IDE 下載&#xff1a;https://www.jetbrains.com/go/ 第一個 golang 程序 package mainimport "fmt"func main() {fmt.Println("hello golang") }每個可執行代碼都必須包含 Pack…

Flutter 狀態管理 Provider

狀態管理必要性 Flutter基于聲明式構建UI&#xff0c;原生則是命令式&#xff0c;狀態管理是用于解決聲明式開發帶來的問題。 例&#xff1a;命令式的原生&#xff0c;數據更新需要拿到對應控件并更改其顯示值&#xff1b;而聲明式則需要更改數據值并通過setstate更新狀態&am…

sql高頻面試題-連續完成兩個指定動作的用戶統計

用戶行為分析 業務背景 某購物APP最近上線了一個新功能&#xff0c;用戶簽到后可以跳轉到大轉盤抽獎&#xff0c;抽獎獲得的獎金可以抵消購物的費用&#xff0c;以此來培養用戶使用app的習慣。 數據表介紹 現有一張用戶行為表action_log&#xff0c;主要字段如下&#xff0c…

springboot mongodb 配置多數據源

我想要的效果是&#xff0c;一個類統一管理多數據源&#xff0c;我傳個參數進去&#xff0c;它就能返回我對應的mongotemplate 但是根據"mongbodb 多數據源"的關鍵詞&#xff0c;找不到我想要的效果。 網上大多都是明確知道自己是幾個數據源&#xff0c;然后每個數…

Styletron: 面向組件的樣式設計工具包

styletron官網&#xff1a; styletron的GitHub鏈接&#xff1a; styletron-react 一. 介紹 Styletron是一個通用的component-oriented&#xff08;面向組件的&#xff09;樣式工具。它屬于css-in-js類別。Styletron可以很好地與React配合使用&#xff0c;但也可以與其他框架或…

docker復現nginx錯誤配置漏洞

目錄 一、nginx環境搭建 1.1搭建步驟 二、docker復現Nginx配置漏洞 2.1安裝docker 2.2復現過程 2.1CRLF(carriage return/line feed)注入漏洞 2.2.目錄穿越 一、nginx環境搭建 1.1搭建步驟 1.先創建Nginx的目錄并進入&#xff08;命令如下&#xff09; mkdir /soft &&…

Android Framework底層原理之WMS的啟動流程

一 概述 今天&#xff0c;我們介紹 WindowManagerService&#xff08;后續簡稱 WMS&#xff09;的啟動流程&#xff0c;WMS 是 Android 系統中&#xff0c;負責窗口顯示的的服務。在 Android 中它也起著承上啟下的作用。 如下圖&#xff0c;就是《深入理解 Android》書籍中的…

033_小馳私房菜_Qcom平臺8系列-Dump Jpeg Jpeg Exif信息修改

全網最具價值的Android Camera開發系列資料~ 作者:8年Android Camera開發,從Camera app一直做到Hal和驅動~ 歡迎訂閱,相信能擴展你的知識面,提升個人能力~ 平臺:高通8系列 jpeg相關代碼邏輯在camx/src/swl/jpeg/ 路徑下 一、Dump Jpeg 有時我們想把hal這邊拍照的jpe…

【C++】STL初識

1.STL的基本概念 2.vector存放內置數據類型 #include <iostream> using namespace std; #include <vector> #include <algorithm>void MyPrint(int val) {cout << val << endl; }void test01() {//創建vector容器對象&#xff0c;并且通過模板參…

Harbor企業鏡像倉庫部署(本地)

簡述&#xff1a; Docker 官方鏡像倉庫是用于管理公共鏡像的地方&#xff0c;大家可以在上面找到想要的鏡像&#xff0c;也可以把自己的鏡像推送上去。但是有時候服務器無法訪問互聯網&#xff0c;或者不希望將自己的鏡像放到互聯網上&#xff0c;那么就需要用到 Docker Regis…

越南的區塊鏈和NFT市場調研

越南的區塊鏈和NFT市場調研 基本介紹 https://zh.wikipedia.org/wiki/%E8%B6%8A%E5%8D%97 語言文字&#xff1a; 越南語&#xff0c; 文字以國語字&#xff08;越南羅馬字&#xff09;為主&#xff0c;漢喃文&#xff08;漢字&#xff09; 貨幣&#xff1a;越南盾 人口(2022…

Leetcode-每日一題【劍指 Offer 15. 二進制中1的個數】

題目 編寫一個函數&#xff0c;輸入是一個無符號整數&#xff08;以二進制串的形式&#xff09;&#xff0c;返回其二進制表達式中數字位數為 1 的個數&#xff08;也被稱為 漢明重量).&#xff09;。 提示&#xff1a; 請注意&#xff0c;在某些語言&#xff08;如 Java&…

如何安全地移動WSL 2 到另一個驅動器

當您擁有小型 SSD 并且適用于 Linux 的 Windows 子系統 (WSL) 的大小呈指數增長時&#xff0c;這真的很痛苦。沒有簡單的方法將 WSL 安裝移動到另一個驅動器。在這篇博客中&#xff0c;我將討論如何通過小步解決這個問題。 1.打開具有管理員訪問權限的 PowerShell或命令提示符…

【Docker】Windows下docker環境搭建及解決使用非官方終端時的連接問題

目錄 背景 Windows Docker 安裝 安裝docker toolbox cmder 解決cmder 連接失敗問題 資料獲取方法 背景 時常有容器方面的需求&#xff0c;經常構建調試導致測試環境有些混亂&#xff0c;所以想在本地構建一套環境&#xff0c;鏡像調試穩定后再放到測試環境中。 Windows …

多線程與高并發--------線程池

線程池 一、什么是線程池 在開發中&#xff0c;為了提升效率的操作&#xff0c;我們需要將一些業務采用多線程的方式去執行。 比如有一個比較大的任務&#xff0c;可以將任務分成幾塊&#xff0c;分別交給幾個線程去執行&#xff0c;最終做一個匯總就可以了。 比如做業務操…

Windows電腦快速搭建FTP服務教程

FTP介紹 FTP&#xff08;File Transfer Protocol&#xff09;是一種用于在計算機網絡上進行文件傳輸的標準協議。它提供了一種可靠的、基于客戶端-服務器模型的方式來將文件從一個主機傳輸到另一個主機。在本文中&#xff0c;我將詳細介紹FTP的工作原理、數據傳輸模式以及常見…