最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的引用和inline 和 nullptr全面解析

 更新時(shí)間:2026年05月11日 10:16:50   作者:.道阻且長.  
文章主要介紹C++中引用的概念、特性及使用方法,包括引用的定義、初始化、作用域、const引用等,并與指針進(jìn)行了對(duì)比,此外,還介紹了內(nèi)聯(lián)函數(shù)和nullptr的關(guān)鍵知識(shí)點(diǎn),感興趣的朋友一起看看吧

一.引用

1.1引用的概念與定義

引?不是新定義?個(gè)變量,?是給已存在變量取了?個(gè)別名,編譯器不會(huì)為引?變量開辟內(nèi)存空間, 它和它引?的變量共?同?塊內(nèi)存空間。?如:?壺傳中李逵,宋江叫"鐵?",江湖上?稱"?旋 ?";林沖,外號(hào)豹?頭;

類型& 引?別名=引?對(duì)象

C++中為了避免引?太多的運(yùn)算符,會(huì)復(fù)?C語?的?些符號(hào),?如前?的>,這?引?也和取 地址使?了同?個(gè)符號(hào)&,?家注意使??法?度區(qū)分就可以。(吐槽?下,這個(gè)問題其實(shí)挺坑的,個(gè) ?覺得?更多符號(hào)反?更好,不容易混淆

從這里我們可以看出,i和j的地址是一樣的,說明他們指向同一塊空間,引用不會(huì)開辟新空間

1.2 引?的特性

1.引?在定義時(shí)必須初始化

2.?個(gè)變量可以有多個(gè)引?

3. 引??旦引??個(gè)實(shí)體,再不能引?其他實(shí)體

這里我們可以看出,引用b指向了a,說明是給a取了別名;若要讓b在指向d,d現(xiàn)在是20,這里就是賦值的意思,將20賦值給b,而b又是a的別名,所以a的值也發(fā)生了改變

4.別名++,其存在的變量也++

1.3 引?的使?

1.3.1引用傳參的使用

1. 引?在實(shí)踐中主要是于引?傳參和引?做返回值中減少拷?提?效率和改變引?對(duì)象時(shí)同時(shí)改變被引?對(duì)象。

2.引?傳參跟指針傳參功能是類似的,引?傳參相對(duì)更?便?些。

如果使用指針來實(shí)現(xiàn)兩個(gè)數(shù)的交換,首先Swap1中的ab需要開辟一個(gè)空間來指向x1,y1的地址,需要拷貝;

若用引用的話,只是給x2,y2起別名,ab發(fā)生改變,x2,y2也同時(shí)發(fā)生改變,但這種情況不會(huì)開辟新空間,不需要拷貝優(yōu)于指針

上面的圖返回的是臨時(shí)變量,是一個(gè)值,需要存儲(chǔ)起來,不能直接進(jìn)行修改;

下面的圖返回的是它的引用,可以進(jìn)行直接修改

3.引?返回值的場景相對(duì)?較復(fù)雜,我們在這?簡單講了?下場景,還有?些內(nèi)容后續(xù)類和對(duì)象章節(jié) 中會(huì)繼續(xù)深?講解。

4.引?和指針在實(shí)踐中相輔相成,功能有重疊性,但是各有特點(diǎn),互相不可替代。C++的引?跟其他 語?的引?(如Java)是有很?的區(qū)別的,除了?法,最?的點(diǎn),C++引?定義后不能改變指向, Java的引?可以改變指向。

5.?些主要?C代碼實(shí)現(xiàn)版本數(shù)據(jù)結(jié)構(gòu)教材中,使?C++引?替代指針傳參,?的是簡化程序,避開 復(fù)雜的指針,但是很多同學(xué)沒學(xué)過引?,導(dǎo)致?頭霧?。

1.3.2傳引用返回

再說傳引用返回,這里返回的是ret的別名

但是這樣的傳引用返回的行為,本質(zhì)上是非常危險(xiǎn)的,func函數(shù)結(jié)束之后,func棧幀就銷毀了,但是tmp依舊是ret這塊空間的別名,tmp依舊在訪問ret,就相當(dāng)于野指針的訪問。此時(shí)返回的就不一定是0了,也有可能是隨機(jī)值

正確傳引用返回:

如圖出了作用域,func1結(jié)束,ret還在,此時(shí)被static修飾的ret就不存在func1的棧幀之中了

1.4 const引用


1.可以引用一個(gè)const對(duì)象,但是必須用const引用。const引用也可以引用普通對(duì)象,因?yàn)閷?duì)象的訪問權(quán)限在引用過程中可以縮小,但是不能放大。

   如圖,如果a被const修飾了,引用就不能使用了,此時(shí)a不能改變,但是b是a的別名,可以改變a,這就是一個(gè)權(quán)限放大的場景,權(quán)限是不能放大的,想要正常引用就要權(quán)限移b也要被const修飾

用const修飾a,a只能讀不能寫;而b是a的引用,沒有用const,那么b既能讀又能寫,放大了a的權(quán)限

這樣寫才是正確的,a和b都只能讀不能寫。

a可讀可寫,但是引用后只能讀不能寫,這樣是正確的,縮小了權(quán)限

2.不需要注意的是類似 int& rb = a*3; double d = 12.34; int& rd = d; 這樣?些場 景下a*3的和結(jié)果保存在?個(gè)臨時(shí)對(duì)象中, int& rd = d 也是類似,在類型轉(zhuǎn)換中會(huì)產(chǎn)?臨時(shí)對(duì) 象存儲(chǔ)中間值,也就是說,rb和rd引?的都是臨時(shí)對(duì)象,?C++規(guī)定臨時(shí)對(duì)象具有常性,所以這? 就觸發(fā)了權(quán)限放?,必須要?常引?才可以。

  • int&非常量左值引用,它只能綁定到一個(gè)可修改的左值(即有內(nèi)存地址的變量)。
  • a * 3 是一個(gè)臨時(shí)右值(計(jì)算結(jié)果是一個(gè)沒有名字的臨時(shí)值,沒有持久的內(nèi)存地址),無法被非常量左值引用綁定。

正確寫法是在引用前面加上const修飾,只能讀。

  • double d = 12.34;定義了一個(gè) double 類型變量 d,值為 12.34。
  • int i = d;
    • double 類型的 d 隱式轉(zhuǎn)換為 int,截?cái)嘈?shù)部分,i 的值為 12
    • 這是直接賦值,i 是一個(gè)獨(dú)立的新變量,和 d 共享內(nèi)存。
  • const int& ri = d;
    • 試圖將 double 類型的 d 綁定到 const int& 類型的引用。
    • 由于類型不匹配,編譯器會(huì)生成一個(gè)臨時(shí)的 int 類型對(duì)象,將 d 截?cái)酁?12 存入該臨時(shí)對(duì)象,然后讓 ri 綁定到這個(gè)臨時(shí)對(duì)象。
    • 這就是圖中標(biāo)注的「臨時(shí)對(duì)象」:它是一個(gè)匿名的、生命周期被 const int& 延長的臨時(shí)變量,ri 并不直接引用 d,而是引用這個(gè)臨時(shí)對(duì)象。

1.5指針與引用的關(guān)系

對(duì)比維度引用(Reference)指針(Pointer)
本質(zhì)概念變量的別名,不單獨(dú)占用內(nèi)存空間存儲(chǔ)變量的內(nèi)存地址,需要占用內(nèi)存空間
初始化要求定義時(shí)必須初始化,且必須綁定到一個(gè)已存在的對(duì)象建議初始化,但語法上不強(qiáng)制,可以先聲明后賦值
指向關(guān)系初始化后無法再更改綁定對(duì)象,始終指向最初綁定的變量可以隨時(shí)改變指向,指向不同的變量或空地址
訪問方式直接使用引用名訪問目標(biāo)對(duì)象,無需解引用需要通過 * 解引用操作符才能訪問目標(biāo)對(duì)象
sizeof 含義sizeof(引用) 結(jié)果為所引用類型的大小(如 sizeof(int&) = 4)sizeof(指針) 結(jié)果為地址空間的字節(jié)數(shù)(32 位平臺(tái)為 4 字節(jié),64 位平臺(tái)為 8 字節(jié))
安全性不存在空引用、野引用問題,使用相對(duì)更安全容易出現(xiàn)空指針、野指針問題,使用時(shí)需額外判斷合法性
典型用途函數(shù)參數(shù)傳遞(避免拷貝)、函數(shù)返回值(保證非空)動(dòng)態(tài)內(nèi)存管理、數(shù)組遍歷、復(fù)雜數(shù)據(jù)結(jié)構(gòu)(鏈表 / 樹)的節(jié)點(diǎn)操作

二、inline

先看一下宏常見的問題

看似沒有問題,但這個(gè)宏在另一種場景下就又不對(duì)了

所以可以看出宏函數(shù)很容易出現(xiàn)問題,很復(fù)雜,還不能調(diào)試

所以C++之父就搞了個(gè)內(nèi)聯(lián)出來

寫個(gè)函數(shù)是不容易寫錯(cuò)的,但寫個(gè)宏函數(shù)很容易寫錯(cuò)
宏函數(shù)的優(yōu)點(diǎn)就是可以提高效率,適用于高頻調(diào)用的小函數(shù),預(yù)處理階段宏會(huì)替換,不建立棧幀,而且宏甚至可以傳類型

C++中內(nèi)聯(lián)就是用來替換宏的

用inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用的時(shí)候展開(不是把函數(shù)部分的代碼直接放到主函數(shù)處,而是把函數(shù)地方的邏輯經(jīng)過一定的處理,經(jīng)過編譯器自己分析,用于主函數(shù)處)內(nèi)聯(lián)函數(shù),這樣調(diào)用內(nèi)聯(lián)函數(shù)就不需要建立棧幀了,就可以提高效率
inline對(duì)于編譯器而言只是一個(gè)建議,也就是說,你加了inline編譯器也可以選擇在調(diào)用的地方不展開,不同編譯器關(guān)于inline什么情況展開各不相同,因?yàn)镃++標(biāo)準(zhǔn)沒有規(guī)定這個(gè)。inline適用于頻繁調(diào)用的短小函數(shù),對(duì)于遞歸函數(shù),代碼相對(duì)多一些的函數(shù),加上inline也會(huì)被編譯器忽略。

三、nullptr

nullptr是C++11的一個(gè)關(guān)鍵字,是用來替代C語言的NULL的

NULL實(shí)際上是一個(gè)宏,在傳統(tǒng)的C頭文件(stddef.h)中,可以看到如下代碼:

#ifndef NULL
    #ifdef __cplusplus
        //C++中的NULL被替換為0,默認(rèn)為整型
        #define NULL    0
    #else
        //C語言中的NULL也被替換為0,但是被強(qiáng)制類型轉(zhuǎn)換為(void*)
        #define NULL    ((void *)0)
    #endif
#endif

C++中NULL可能被定義為字面常量0,或者C中被定義為無類型指針(void * )的常量。不論采取何種定義,在使用空值的指針時(shí),都不可避免的會(huì)遇到一些麻煩,本想通過f(NULL)調(diào)用指針版本的f(int * )函數(shù),但是由于NULL被定義成0,調(diào)用了f(int x),因此與程序的初衷相悖。f((void* )NULL);調(diào)用會(huì)報(bào)錯(cuò)

在C++之中,void* 給int* 是需要強(qiáng)制類型轉(zhuǎn)換的
C++11中引用nullptr,nullptr是一個(gè)特殊的關(guān)鍵字(就相當(dāng)于語法層在編譯的時(shí)候就特殊解決該問題了),nullptr是一種特殊類型的字面量,它可以轉(zhuǎn)換成任意其它類型的指針類型(值還為0)。使用nullptr定義空指針可以避免類型轉(zhuǎn)換的問題,因?yàn)閚ullptr只能被隱式轉(zhuǎn)換為指針類型,而不能被轉(zhuǎn)換為整數(shù)類型。

到此這篇關(guān)于C++中的引用和inline 和 nullptr全面解析的文章就介紹到這了,更多相關(guān)C++引用和inline 和 nullptr內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C語言內(nèi)核字符串拷貝與比較

    詳解C語言內(nèi)核字符串拷貝與比較

    本文將探索一下字符串的拷貝與比較,與應(yīng)用層不同內(nèi)核字符串拷貝與比較也需要使用內(nèi)核專用的API函數(shù),字符串的拷貝往往伴隨有內(nèi)核內(nèi)存分配,我們將首先簡單介紹內(nèi)核如何分配堆空間,然后再以此為契機(jī)簡介字符串的拷貝與比較
    2022-09-09
  • c語言中static和extern的用法詳細(xì)解析

    c語言中static和extern的用法詳細(xì)解析

    以下是對(duì)c語言中static和extern的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-09-09
  • C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能

    C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能

    這篇文章主要介紹了C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能,幫助大家提高程序運(yùn)行速度,感興趣的朋友可以了解下
    2020-10-10
  • VsCode配置C++/Cmake的步驟詳解

    VsCode配置C++/Cmake的步驟詳解

    本文分步驟給大家介紹VsCode配置C++/Cmake的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-07-07
  • C++?std::copy與memcpy區(qū)別小結(jié)

    C++?std::copy與memcpy區(qū)別小結(jié)

    本文主要介紹了C++?std::copy與memcpy區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • C++11中的智能指針和垃圾回收使用

    C++11中的智能指針和垃圾回收使用

    本文主要介紹了C++11中的智能指針和垃圾回收使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • C語言實(shí)現(xiàn)手寫Map(全功能)的示例代碼

    C語言實(shí)現(xiàn)手寫Map(全功能)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)手寫Map(全功能),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-08-08
  • C++類模板實(shí)戰(zhàn)之vector容器的實(shí)現(xiàn)

    C++類模板實(shí)戰(zhàn)之vector容器的實(shí)現(xiàn)

    本文我們將做一個(gè)類模板實(shí)戰(zhàn)-手寫精簡版vector容器。讓我們自己封裝一個(gè)數(shù)組類,可以適應(yīng)基本數(shù)據(jù)類型和自定義數(shù)據(jù)類型,感興趣的可以了解一下
    2022-07-07
  • Qt編寫提示進(jìn)度條的實(shí)現(xiàn)示例

    Qt編寫提示進(jìn)度條的實(shí)現(xiàn)示例

    進(jìn)度條在很地方都可以使用到,Qt自帶的進(jìn)度條或者操作系統(tǒng)的進(jìn)度條樣式,不夠炫,本文就介紹一下Qt編寫自定義控件的提示進(jìn)度條的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2021-12-12
  • C++實(shí)現(xiàn)LeetCode(100.判斷相同樹)

    C++實(shí)現(xiàn)LeetCode(100.判斷相同樹)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(100.判斷相同樹),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評(píng)論

常州市| 普格县| 乳山市| 聂拉木县| 禄劝| 河津市| 新干县| 延吉市| 奎屯市| 怀集县| 靖西县| 南平市| 万年县| 华亭县| 房产| 锦屏县| 京山县| 稷山县| 安远县| 乐都县| 潜江市| 万盛区| 合阳县| 马鞍山市| 遂宁市| 南和县| 成武县| 苍南县| 渭南市| 伊宁县| 和田县| 宜州市| 遵化市| 锡林浩特市| 蒙自县| 米泉市| 镇赉县| 岫岩| 东莞市| 会宁县| 蕲春县|