【C++基礎】初識C++(2)--引用、const、inline、nullptr

目錄

一、引用

1.1? 引用的概念和定義

1.2? 引用的特性

1.3引用的使用

1.4? const引用

1.5? 指針和引用的關系

二、inline

三、nullptr


一、引用

1.1? 引用的概念和定義

引?不是新定義?個變量,?是給已存在變量取了?個別名,編譯器不會為引?變量開辟內存空間,它和它引?的變量共?同?塊內存空間。?如:水滸傳中的林沖,外號豹?頭;

類型& 引用別名 = 引用對象;

舉個栗子:

#include<iostream>
using namespace std;
int main()
{int a = 0;
// 引?:b和c是a的別名int& b = a;int& c = a;
// 也可以給別名b取別名,d相當于還是a的別名int& d = b;++d;
// 這?取地址我們看到是?樣的cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &d << endl;return 0;
}

?

注:C++中為了避免引?太多的運算符,會復?C語?的?些符號,?如前?的 <<和 >>,這?引?也和取地址使?了同?個符號&,?家注意使??法?度區分就可以

1.2? 引用的特性

  • 引?在定義時必須初始化
  • ?個變量可以有多個引?
  • 引??旦引??個實體,再不能引?其他實體
#include<iostream>
using namespace std;
int main()
{int a = 10;
// 編譯報錯:“ra”: 必須初始化引?//int& ra;int& b = a;int c = 20;
// 這?并?讓b引?c,因為C++引?不能改變指向,
// 這?是?個賦值b = c;cout << &a << endl;cout << &b << endl;cout << &c << endl;return 0;
}

1.3引用的使用

  • 引?在實踐中主要是于引?傳參和引?做返回值中減少拷?提?效率改變引?對象時同時改變被引?對象
  • 引?傳參跟指針傳參功能是類似的,引?傳參相對更?便?些。
  • 引?和指針在實踐中相輔相成,功能有重疊性,但是各有特點,互相不可替代。C++的引?跟其他語?的引?(如Java)是有很?的區別的,除了?法,最?的點,C++引?定義后不能改變指向,Java的引?可以改變指向。

?之前我們在另一個函數交換值需要傳地址, 有了引用就可以直接傳引用,此時rx就相當于x的別名, 而ry就相當于y的別名

void Swap(int& rx, int& ry)
{int tmp = rx;rx = ry;ry = tmp;
} 
int main()
{int x = 0, y = 1;cout << x <<" " << y << endl;Swap(x, y);cout << x << " " << y << endl;return 0;
}

雖然它的底層邏輯是指針,但在語法上是取別名,不要想底層,會將其搞復雜

看下面這個代碼,原C語言中的指針,現用引用替代

#include<iostream>
using namespace std;
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
void STInit(ST& rs, int n = 4)
{rs.a = (STDataType*)malloc(n * sizeof(STDataType));rs.top = 0;rs.capacity = n;
} 
// 棧頂
void STPush(ST& rs, STDataType x)
{
// 滿了, 擴容if (rs.top == rs.capacity){printf("擴容\n");int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;STDataType* tmp = (STDataType*)realloc(rs.a, newcapacity *sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;} rs.a = tmp;rs.capacity = newcapacity;} rs.a[rs.top] = x;rs.top++;
} int& STTop(ST& rs)
{assert(rs.top > 0);return rs.a[rs.top];
} 
int main()
{
// 調?全局的ST st1;STInit(st1);STPush(st1, 1);STPush(st1, 2);cout << STTop(st1) << endl;STTop(st1) += 10;cout << STTop(st1) << endl;return 0;
}

還有這個是許多教材上喜歡寫的,以前C語言的時候是不是很懵啊?,?些主要?C代碼實現版本數據結構教材中,使?C++引?替代指針傳參,?的是簡化程序,避開復雜的指針,但是很多同學沒學過引?,導致?頭霧?

#include<iostream>
using namespace std;
typedef struct SeqList
{int a[10];int size;
}SLT;void SeqPushBack(SLT& sl, int x)
{}
typedef struct ListNode
{int val;struct ListNode* next;
}LTNode, *PNode;// 指針變量也可以取別名,這?LTNode*& phead就是給指針變量取別名// 這樣就不需要??級指針了,相對??簡化了程序//void ListPushBack(LTNode** phead, int x)//void ListPushBack(LTNode*& phead, int x)
void ListPushBack(PNode& phead, int x)
{PNode newnode = (PNode)malloc(sizeof(LTNode));newnode->val = x;newnode->next = NULL;if (phead == NULL){phead = newnode;} else{//...}
}
int main()
{PNode plist = NULL;ListPushBack(plist, 1);return 0;
}

1.4? const引用

? 可以引??個const對象,但是必須?const引?。const引?也可以引?普通對象,因為對象的訪問權限在引?過程中可以縮?,但是不能放?
? 不需要注意的是類似 int& rb = a*3; double d = 12.34; int& rd = d; 這樣?些場景下a*3的和結果保存在?個臨時對象中, int& rd = d 也是類似,在類型轉換中會產?臨時對象存儲中間值,也就是時,rb和rd引?的都是臨時對象,?C++規定臨時對象具有常性,所以這?就觸發了權限放?,必須要?常引?才可以。
? 所謂臨時對象就是編譯器需要?個空間暫存表達式的求值結果時臨時創建的?個未命名的對象,C++中把這個未命名對象叫做臨時對象

舉個栗子:?

int main()
{const int a = 10;// 編譯報錯:error C2440: “初始化”: ?法從“const int”轉換為“int &”// 這?的引?是對a訪問權限的放?//int& ra = a;  //報錯const int& ra = a;// 這樣才可以// 編譯報錯:error C3892: “ra”: 不能給常量賦值//ra++;// 這?的引?是對b訪問權限的縮?int b = 20;const int& rb = b;// 編譯報錯:error C3892: “rb”: 不能給常量賦值//rb++;return 0;
}
#include<iostream>
using namespace std;
int main()
{int a = 10;const int& ra = 30;// 編譯報錯: “初始化”: ?法從“int”轉換為“int &”// int& rb = a * 3; //errorconst int& rb = a * 3;//rightdouble d = 12.34;// 編譯報錯:“初始化”: ?法從“double”轉換為“int &”// int& rd = d; //errorconst int& rd = d; //rightreturn 0;
}

權限放大只存在于指針和引用中,下面這兩種不要搞混了?

?

1.5? 指針和引用的關系

C++中指針和引?就像兩個性格迥異的親兄弟,指針是哥哥,引?是弟弟,在實踐中他們相輔相成,功能有重疊性,但是各有??的特點,互相不可替代。
? 語法概念引?是?個變量的取別名不開空間指針是存儲?個變量地址,要開空間
? 引?在定義時必須初始化指針建議初始化,但是語法上不是必須的
? 引?在初始化時引??個對象后,就不能再引?其他對象;?指針可以在不斷地改變指向對象
? 引?可以直接訪問指向對象指針需要解引?才是訪問指向對象
? sizeof中含義不同,引?結果為引?類型的??,但指針始終是地址空間所占字節個數(32位平臺下占4個字節,64位下是8byte)
? 指針很容易出現空指針和野指針的問題,引?很少出現,引?使?起來相對更安全?些。

int main()
{int a = 0;int* p = &a;*p = 1;int& ra = a;ra = 2;return 0;
}

這串代碼通過vs中的反匯編可以看出,指針和引用在底層是一樣的,這里大家做一個了解就行了

二、inline

? ?inline修飾的函數叫做內聯函數,編譯時C++編譯器會在調?的地?展開內聯函數,這樣調?內聯函數就需要建?棧幀了,就可以提?效率。
? inline對于編譯器??只是?個建議,也就是說,你加了inline編譯器也可以選擇在調?的地?不展開,不同編譯器關于inline什么情況展開各不相同,因為C++標準沒有規定這個。inline適?于頻繁調?的短?函數,對于遞歸函數,代碼相對多?些的函數,加上inline也會被編譯器忽略。
? C語?實現宏函數也會在預處理時替換展開,但是宏函數實現很復雜很容易出錯的,且不?便調試,C++設計了inline?的就是替代C的宏函數
? inline不建議聲明和定義分離到兩個?件,分離會導致鏈接錯誤。因為inline被展開,就沒有函數地址,鏈接時會出現報錯。

#include<iostream>
using namespace std;
inline int Add(int x, int y)
{int ret = x + y;//ret += 1;//ret += 1;//ret += 1;//...return ret;
} 
int main()
{// 可以通過匯編觀察程序是否展開// 有call Add語句就是沒有展開,沒有就是展開了int ret = Add(1, 2);cout << Add(1, 2) * 5 << endl;return 0;
}

?

這里說一下 vs 編譯器debug版本下?默認是不展開inline的,這樣?便調試,debug版本想展開需要設置?下以下兩個地?

三、nullptr

NULL實際是?個宏,在傳統的C頭?件(stddef.h)中,可以看到如下代碼:

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

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

? C++11中引?nullptr,nullptr是?個特殊的關鍵字,nullptr是?種特殊類型的字?量,它可以轉換
成任意其他類型的指針類型
。使?nullptr定義空指針可以避免類型轉換的問題,因為nullptr只能被
隱式地轉換為指針類型,?不能被轉換為整數類型

#include<iostream>
using namespace std;
void f(int x)
{cout << "f(int x)" << endl;
} 
void f(int* ptr)
{cout << "f(int* ptr)" << endl;
} 
int main()
{f(0);
// 本想通過f(NULL)調?指針版本的f(int*)函數,
//但是由于NULL被定義成0,調?了f(intx),因此與程序的初衷相悖。f(NULL);f((int*)NULL);
// 編譯報錯:error C2665: “f”: 2 個重載中沒有?個可以轉換所有參數類型
// f((void*)NULL);f(nullptr);return 0;
}

本篇到這里就結束了,如有問題歡迎在評論區指正。感謝!下篇見!

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

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

相關文章

微軟的人工智能語音生成器在測試中達到與人類同等水平

微軟公司開發了一種新的神經編解碼語言模型 Vall-E&#xff0c;在自然度、語音魯棒性和說話者相似性方面都超越了以前的成果。它是同類產品中第一個在兩個流行基準測試中達到人類同等水平的產品&#xff0c;而且顯然非常逼真&#xff0c;以至于微軟不打算向公眾開放。 VALL-E …

Node.js 模塊系統

Node.js 模塊系統 Node.js 的模塊系統是其核心特性之一,它允許開發者將代碼組織成可重用的模塊。這種系統促進了代碼的模塊化,使得大型應用程序的構建和管理變得更加容易。本文將深入探討 Node.js 的模塊系統,包括其工作原理、如何創建和使用模塊,以及模塊系統的優勢和局限…

【每日一練】python類和對象現實舉例詳細講解

""" 本節課程目的&#xff1a; 1.掌握類描述現實世界實物思想 2.掌握類和對象的關系 3.理解什么事面向對象 """ #比如設計一個鬧鐘&#xff0c;在這里就新建一個類 class Clock:idNone #鬧鐘的序列號&#xff0c;也就是類的屬性priceNone #鬧…

Git最常用操作速查表

Git常用操作 文章目錄 Git常用操作1. 克隆/拉取2. 分支操作1. 查看分支2. 創建分支3. 切換到分支4. 刪除分支5. 刪除遠程分支6. 推送分支到遠程 3. 暫存庫操作4. Git團隊規范1. 原則2. 分支設計3. commit備注一般規范 1. 克隆/拉取 git clone xxx 從遠程倉庫克隆 git rebase…

【開源之美】:WinMerge Files

一、引言 強大的windows端文件比較工具&#xff0c;跟Beyond Compare相比&#xff0c;更為強大。但是這里我們推薦他的原因&#xff0c;不僅是因為作為一個使用的工具&#xff0c;主要是因為他開源&#xff0c;可以通過調試優秀的源代碼&#xff0c;進一步的提升C項目設計和編…

Alternative to Receptive field in Transformers and what factors impact it

題意&#xff1a;Transformer中感受野的替代概念及其影響因素 問題背景&#xff1a; I have two transformer networks. One with 3 heads per attention and 15 layers in total and second one with 5 heads per layer and 30 layers in total. Given an arbitrary set of d…

什么是數據模型?數據模型與數據治理有什么關系?

在企業數據治理的廣闊領域中&#xff0c;首要且關鍵的一步是明確溝通數據治理的需求。這包括對企業所持有的數據種類、數據存儲位置、以及當前數據管理的具體情況有一個清晰的了解和記錄。了解企業的數據資產是制定有效數據治理策略的基礎。企業需要識別和盤點所有類型的數據資…

AIGC產品經理學習路徑

基礎篇&#xff08;課時 2 &#xff09; AIGC 行業視角 AIGC 的行業發展演進&#xff1a;傳統模型/深度學習/大模型 AIGC 的產品設計演進&#xff1a;AI Embedded / AI Copilot / AI Agen AIGC 的行業產業全景圖 AIGC 的產品應用全景圖 AIGC 職業視角 AI 產品經理/ AIGC…

2974.最小數字游戲

1.題目描述 你有一個下標從 0 開始、長度為 偶數 的整數數組 nums &#xff0c;同時還有一個空數組 arr 。Alice 和 Bob 決定玩一個游戲&#xff0c;游戲中每一輪 Alice 和 Bob 都會各自執行一次操作。游戲規則如下&#xff1a; 每一輪&#xff0c;Alice 先從 nums 中移除一個 …

Spring MVC 全面指南:從入門到精通的詳細解析

引言&#xff1a; Spring MVC&#xff0c;作為Spring框架的一個重要模塊&#xff0c;為構建Web應用提供了強大的功能和靈活性。無論是初學者還是有一定經驗的開發者&#xff0c;掌握Spring MVC都將顯著提升你的Web開發技能。本文旨在為初學者提供一個全面且易于理解的學習路徑…

數據建設實踐之大數據平臺(五)安裝hive

安裝hive 上傳安裝包到/opt/software目錄并解壓 [bigdata@node101 software]$ tar -zxvf hive-3.1.3-with-spark-3.3.1.tar.gz -C /opt/services [bigdata@node101 services]$ mv apache-hive-3.1.3-bin apache-hive-3.1.3 配置環境變量 export JAVA_HOME=/opt/services…

Debezium系列之:驗證mysql、mariadb等兼容mysql協議數據庫賬號權限

Debezium系列之:驗證mysql、mariadb等兼容mysql協議數據庫賬號權限 一、數據庫需要開啟binlog二、創建賬號和賬號需要賦予的權限三、賬號具有權限查看日志信息四、驗證賬號權限五、驗證賬號能否執行show master status六、驗證數據庫是否開啟binlog一、數據庫需要開啟binlog …

實驗9 存儲過程與函數的創建管理實驗

一、實驗目的&#xff1a; 理解存儲過程和函數的概念。掌握創建存儲過程和函數的方法。掌握執行存儲過程和函數的方法。掌握游標的定義、使用方法。 二、實驗內容 1&#xff0e;某超市的食品管理的數據庫的Food表&#xff0c;Food表的定義如表所示&#xff0c; Food表的定義…

【進階篇-Day8:JAVA中遞歸、異常的介紹】

目錄 1、遞歸的介紹和使用1.1 遞歸的介紹1.2 案例案例一&#xff1a;案例二&#xff1a;案例三&#xff1a;案例四&#xff1a; 1.3 總結 2、異常的介紹和使用2.1 異常的介紹&#xff1a;&#xff08;1&#xff09;能夠看懂異常&#xff08;2&#xff09;異常的體系接口和分類&…

Go語言map并發安全,互斥鎖和讀寫鎖誰更優?

并發編程是 Go 語言的一大特色&#xff0c;合理地使用鎖對于保證數據一致性和提高程序性能至關重要。 在處理并發控制時&#xff0c;sync.Mutex&#xff08;互斥鎖&#xff09;和 sync.RWMutex&#xff08;讀寫鎖&#xff09;是兩個常用的工具。理解它們各自的優劣及擅長的場景…

蘋果入局,AI手機或將實現“真智能”?

【潮汐商業評論/原創】 “AI應用智能手機不就是現在的AI手機。” 當被問到現階段對AI手機的看法時&#xff0c;John如是說。“術業有專攻&#xff0c;那么多APP在做AI功能&#xff0c;下載用就是了&#xff0c;也用不著現在換個AI手機啊。” 對于AI手機&#xff0c;或許大多…

上海市計算機學會競賽平臺2023年1月月賽丙組積木染色(二)

題目描述 &#x1d45b;n 塊積木排成一排&#xff0c;需要給每塊積木染色&#xff0c;顏色有 &#x1d45a;m 種。請問有多少種方法&#xff0c;從第二塊積木開始統計&#xff0c;恰有 &#x1d45d;p 塊積木與前一塊積木顏色不同&#xff1f; 輸入格式 三個整數分別表示 &a…

Windows安裝和使用Doccano標注工具

簡介 開源鏈接&#xff1a;GitHub - doccano/doccano: Open source annotation tool for machine learning practitioners. Open source annotation tool for machine learning practitioners. Doccano是一款開源的文本標注工具&#xff0c;由人工智能公司Hironsan開發并在G…

【算法】代碼隨想錄之數組

文章目錄 前言 一、二分查找法&#xff08;LeetCode--704&#xff09; 二、移除元素&#xff08;LeetCode--27&#xff09; 三、有序數組的平方&#xff08;LeetCode--977&#xff09; 四、長度最小的子數組&#xff08;LeetCode--209&#xff09; 五、螺旋矩陣II&#x…

花幾千上萬學習Java,真沒必要!(二)

1、注釋&#xff1a; java代碼注釋分3種&#xff1a; 單行注釋&#xff1a;//注釋信息 多行注釋: /*注釋信息*/ 文檔注釋:/**注釋信息*/ public class TestComments {// 這是單行注釋&#xff0c;用于注釋單行代碼或解釋代碼功能/* 這是多行注釋&#xff0c;用于注釋多行代碼…