c++ 二級指針 vs 指針引用

二級指針 vs 指針引用:深入對比與分析

在C++中,二級指針和指針引用都可以用于修改外部指針,但它們在語法、安全性和使用場景上有重要區別。下面我將從多個維度進行詳細對比。

1. 基本概念

1.1 二級指針 (Pointer to Pointer)

int a = 10;
int* p = &a;
int** pp = &p;  // pp是指向指針p的指針

內存布局:

pp → p → a

1.2 指針引用 (Pointer Reference)

int a = 10;
int* p = &a;
int*& pRef = p;  // pRef是p的引用

內存布局:

pRef ? p → a
(引用不占獨立內存空間)

2. 語法對比

2.1 函數參數聲明

// 二級指針版本
void func(int** pp);// 指針引用版本
void func(int*& pRef);

2.2 函數調用

int* ptr = nullptr;// 二級指針調用
func(&ptr);  // 需要顯式取地址// 指針引用調用
func(ptr);   // 直接傳遞指針

2.3 函數內部使用

// 二級指針
*pp = new int(10);  // 需要解引用// 指針引用
pRef = new int(10); // 直接賦值
應用
//二級指針
void allocate(int** pp) {*pp = new int(20);
}int main() {int* p;allocate(&p);  // 需要取地址delete p;
}
//指針引用
void allocate(int*& ptrRef) {ptrRef = new int(20);  // 直接修改外部指針
}int main() {int* p = nullptr;allocate(p);  // p現在指向新分配的intdelete p;
}

3. 底層實現差異

3.1 二級指針實現

  • 實際傳遞指針變量的地址
  • 需要額外的解引用操作
  • 匯編層面表現為雙重間接尋址
; int** pp 參數
mov rax, QWORD PTR [rdi]  ; 加載pp指向的地址
mov QWORD PTR [rax], 10   ; 修改目標指針

3.2 指針引用實現

  • 編譯器自動處理為指針的指針
  • 語法上隱藏了解引用
  • 匯編代碼與二級指針類似但更簡潔
; int*& pRef 參數
mov QWORD PTR [rdi], 10   ; 直接修改目標指針

4. 關鍵區別總結

特性二級指針指針引用
語法復雜度高(需要&和*操作)低(直接使用)
可讀性較低較高
空值安全性需要檢查nullptr不能綁定到nullptr
重新綁定可以修改指向的指針不能重新綁定
C兼容性兼容C僅C++
模板元編程適用性更靈活有時受限
編譯器優化可能多一層間接尋址可能更易優化

5. 使用場景推薦

5.1 使用二級指針的情況

  • 需要兼容C語言的代碼
  • 需要表示可選指針參數(可以傳遞nullptr)
  • 需要動態改變指向的指針目標
  • 在低級內存操作或系統編程中
void allocate(int size, int** outPtr) {if (size > 0) {*outPtr = malloc(size);  // C風格分配} else {*outPtr = nullptr;       // 可以設置為空}
}

5.2 使用指針引用的情況

  • 純C++項目
  • 需要更簡潔的語法
  • 確保指針參數必須有效
  • 需要修改智能指針時
void resizeVector(std::vector<int>*& vecPtr) {if (vecPtr->capacity() < 100) {auto newVec = new std::vector<int>(200);// ...數據遷移...delete vecPtr;vecPtr = newVec;  // 直接替換指針}
}

6. 性能考慮

在優化良好的編譯器中:

  • 指針引用通常能生成與二級指針相同的機器碼
  • 引用可能提供更好的優化機會(別名分析更簡單)
  • 實際性能差異通常可以忽略不計

7. 代碼示例對比

7.1 鏈表節點刪除

二級指針版本

void deleteNode(Node** head, int target) {Node** curr = head;while (*curr) {if ((*curr)->data == target) {Node* temp = *curr;*curr = (*curr)->next;delete temp;return;}curr = &(*curr)->next;}
}

指針引用版本

void deleteNode(Node*& head, int target) {Node* curr = head;Node* prev = nullptr;while (curr) {if (curr->data == target) {if (prev) {prev->next = curr->next;} else {head = curr->next;}delete curr;return;}prev = curr;curr = curr->next;}
}

8. 現代C++最佳實踐

  1. 優先使用指針引用

    • 更清晰的表達意圖
    • 減少錯誤使用指針的可能性
    • 與智能指針配合更好
  2. 考慮使用智能指針引用

    void process(std::unique_ptr<int>& ptr) {*ptr = 42;ptr.reset(new int(100));
    }
    
  3. 需要兼容C或特殊場景時使用二級指針

9. 總結

二級指針和指針引用本質上都是通過間接方式修改原始指針,但:

  • 指針引用提供了:

    • 更簡潔的語法
    • 更好的類型安全性
    • 更清晰的代碼表達力
  • 二級指針提供了:

    • 與C的兼容性
    • 處理nullptr的能力
    • 更底層的控制

在實際開發中,純C++項目應優先使用指針引用,而在需要與C交互或特殊情況下使用二級指針。

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

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

相關文章

【Hive入門】Hive與Spark SQL深度集成:通過Spark ThriftServer高效查詢Hive表

目錄 引言 1 Spark ThriftServer架構解析 1.1 核心組件與工作原理 1.2 與傳統HiveServer2的對比 2 Spark ThriftServer部署指南 2.1 環境準備與啟動流程 2.1.1 前置條件檢查 2.1.2 服務啟動流程 2.2 高可用部署方案 2.2.1 基于ZooKeeper的HA架構 3 性能優化實戰 3.…

[面試]SoC驗證工程師面試常見問題(二)

SoC驗證工程師面試常見問題(二) 摘要:面試SoC驗證工程師時,SystemVerilog (SV) 和 UVM (Universal Verification Methodology) 是核心技能,而AXI總線是現代SoC中最常見的接口協議之一,因此也是必考點。以下是可能被問到的問題及優質答案的詳細列表: 一、 System…

vue3 css模擬語音通話不同語音、正在加載等的效果

實現效果如下&#xff1a; 在不同的時間&#xff0c;顯示不一樣的效果&#xff08;大小是一樣的&#xff0c;截圖時尺寸發生了變化&#xff09; 具體實現代碼如下&#xff1a; <script setup> import {ref} from "vue";const max_hight ref(40px) const min…

KeyPresser 一款自動化按鍵工具

1. 簡介 KeyPresser 是一款自動化按鍵工具,它可以與窗口交互,并支持后臺運行, 無需保持被控窗口在前臺運行。用戶可以選擇要操作的目標窗口,并通過勾選復選框來控制要發送哪些按鍵消息。可以從組合框中選擇所需的按鍵,并在編輯框中輸入時間間隔以控制按鍵發送之間的延遲。程…

ai之paddleOCR 識別PDF python312和paddle版本沖突 GLIBCXX_3.4.30

這里寫自定義目錄標題 問題一**解決方案****方法 1&#xff1a;使用符號鏈接將系統庫鏈接到 Conda 環境** **補充說明****驗證修復結果** 問題二&#xff1a;**問題根源****解決方案****1. 確認 TensorRT 安裝狀態****2. 安裝 TensorRT 并配置環境變量****3. 驗證 TensorRT 與 …

【RabbitMQ】 RabbitMQ快速上手

文章目錄 一、RabbitMQ 核心概念1.1 Producer和Consumer2.2 Connection和Channel2.3 Virtual host2.4 Queue2.5 Exchange2.6 RabbitMQ工作流程 二、AMQP協議三 、web界面操作4.1 用戶相關操作4.2 虛擬主機相關操作 四、RabbitMQ快速入門4.1 引入依賴4.2 編寫生產者代碼4.2.1 創…

Beatoven AI 自動生成音樂

Beatoven AI 自動生成音樂 文章目錄 Beatoven AI 自動生成音樂一、源代碼二、準備工作1. 安裝 Python 環境2. 安裝依賴庫 三、配置 API 密鑰四、運行腳本示例一&#xff1a;使用默認參數示例二&#xff1a;生成一段電影預告片風格音樂&#xff08;30秒&#xff09; 五、生成結果…

筆試專題(十四)

文章目錄 mari和shiny題解代碼 體操隊形題解代碼 二叉樹中的最大路徑和題解代碼 mari和shiny 題目鏈接 題解 1. 可以用多狀態的線性dp 2. 細節處理&#xff1a;使用long long 存儲個數 3. 空間優化&#xff1a;只需要考慮等于’s’&#xff0c;‘sh’&#xff0c;shy’的情況…

LeetCode —— 94. 二叉樹的中序遍歷

&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?Take your time ! &#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?&#x1f636;?&#x1f32b;?…

conda相關操作

安裝torch 直接使用conda install torch1.12.0會報錯&#xff0c;因為 Conda 通常使用 pytorch 作為包名&#xff08;而非 torch&#xff09; 正確使用方法&#xff1a; conda install pytorch1.12.0 -c pytorch使用 pip 安裝 pip install torch1.12.0在 Conda 中查看可安裝…

【Java面試筆記:進階】26.如何監控和診斷JVM堆內和堆外內存使用?

監控和診斷JVM內存使用是優化性能和解決內存問題的關鍵。 1.JVM內存監控與診斷方法 1.圖形化工具 JConsole:提供圖形化界面,可直接連接到Java進程,查看內存使用情況。VisualVM:功能強大的圖形化工具,但注意從Oracle JDK 9開始不再包含在JDK安裝包中。Java Mission Contr…

AVIOContext 再學習

這個目前階段用的不多&#xff0c;暫時不要花費太多精力。 url 的格式不同&#xff0c;使用的傳輸層協議也不同。這塊看代碼還沒看到自己想的這樣。 目前看的信息是&#xff1a;avformatContext 的 io_open 回調函數 在默認情況下叫 io_open_default&#xff0c;在解復用的 av…

在Java項目中實現本地語音識別與熱點檢測,并集成阿里云智能語音服務

引言 隨著語音交互技術的發展&#xff0c;如何高效地處理用戶的語音輸入成為許多應用的重要課題。本文將詳細介紹如何在一個Java項目中同時實現&#xff1a; 基于Vosk的本地語音識別&#xff1a;無需調用云端API即可完成語音到文本的轉換。本地熱點語音內容識別&#xff1a;對…

第15章 對API的身份驗證和授權

第15章 對API的身份驗證和授權 在構建RESTful API時,確保只有經過身份驗證和授權的用戶才能訪問特定資源是至關重要的。身份驗證是確認用戶身份的過程,而授權則是決定用戶是否有權訪問特定資源的過程。在本章中,我們將詳細探討如何在ASP.NET Core Web API中實現身份驗證和授…

asp.net客戶管理系統批量客戶信息上傳系統客戶跟單系統crm

# crm-150708 客戶管理系統批量客戶信息上傳系統客戶跟單系統 # 開發背景 本軟件是給鄭州某企業管理咨詢公司開發的客戶管理系統軟件 # 功能 1、導入客戶數據到系統 2、批量將不同的客戶分配給不同的業務員跟進 3、可以對客戶數據根據緊急程度標記不同的顏色&#xff0c…

深入理解現代JavaScript:從ES6+語法到Fetch API

引言 JavaScript作為Web開發的基石語言&#xff0c;近年來經歷了翻天覆地的變化。ES6(ECMAScript 2015)的發布帶來了革命性的新特性&#xff0c;而現代瀏覽器提供的API也讓前端開發變得更加強大和高效。本文將深入探討ES6核心語法、DOM操作優化技巧以及使用Fetch API進行異步請…

仙盟創夢IDE-智能編程,C#判斷數組中是否存在key

一、net4 net core版本 使用LINQ的Contains方法 string[] array { "apple", "banana", "cherry" };string key "banana";bool exists array.Contains(key);if (exists){Console.WriteLine($"數組中存在鍵 {key}");}else…

360驅動大師v2.0(含網卡版)驅動工具軟件下載及安裝教程

1.軟件名稱&#xff1a;360驅動大師 2.軟件版本&#xff1a;2.0 3.軟件大小&#xff1a;218 MB 4.安裝環境&#xff1a;win7/win10/win11 5.下載地址&#xff1a; https://www.kdocs.cn/l/cdZMwizD2ZL1?RL1MvMTM%3D 提示&#xff1a;先轉存后下載&#xff0c;防止資源丟失&…

2025年- H22-Lc130-206. 反轉鏈表(鏈表)---java版

1.題目描述 2.思路 使用迭代法 (1)定義一個前指針 (2)然后定義兩個變量 curr&#xff08;head&#xff09;&#xff0c;curr.next。 (3)curr和curr.next交換位置&#xff08;只要當前指針不為空&#xff0c;執行兩兩交換&#xff09; 3.代碼實現 /*** Definition for singly-…

機器學習常用評價指標

1. 指標說明 (1) AccuracyClassification&#xff08;準確率&#xff09; ? 計算方式&#xff1a;accuracy_score(y_true, y_pred) ? 作用&#xff1a; 衡量模型正確預測的樣本比例&#xff08;包括所有類別&#xff09;。 公式&#xff1a; Accuracy TP TN TP TN FP…