【C/C++】區分0、NULL和nullptr

🦄個人主頁:小米里的大麥-CSDN博客

🎏所屬專欄:C++_小米里的大麥的博客-CSDN博客

🎁代碼托管:C++: 探索C++編程精髓,打造高效代碼倉庫 (gitee.com)

??操作環境:Visual Studio 2022

目錄

1. 0 和空指針

2. NULL

3. nullptr

總結?

共勉


在C/C++中,0NULLnullptr 都表示指針的空值,但它們有不同的語義和使用場景。

1. 0 和空指針

在C和C++98中,數字 0 常常被用作空指針的表示。因為C語言規定整型常量 0 可以隱式轉換為任意類型的指針值,所以使用 0 作為空指針值是合法的。

int* p1 = 0;  // 合法,p1 是空指針

但是,使用 0 來表示空指針時,代碼的可讀性可維護性較差,因為 0 既可以表示數值也可以表示指針。因此C++引入了 NULL 來代替 0

2. NULL

NULL 是在C語言的標準頭文件 <stddef.h> 或 C++ 的 <cstddef> 中定義的,通常定義為 ((void*)0) 或單純的 0。在C++98中,它仍然可能會與整型 0 混淆,因為它本質上是 0

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

使用 NULL 來表示空指針可以提高代碼的可讀性,避免誤將數字 0 和指針值混淆。 但因為 NULL 是宏,使用它仍然有一些潛在的問題,尤其是當函數重載涉及不同類型時。

#include <iostream>void Fun(int p) {std::cout << "Fun(int)" << std::endl;
}void Fun(int* p) {std::cout << "Fun(int*)" << std::endl;
}int main() {Fun(0);       // 調用 Fun(int)Fun(NULL);    // 調用 Fun(int) 因為 NULL 被定義為 0
}
在這個例子中,Fun(NULL) 實際上調用了 Fun(int),而不是期望的 Fun(int*),因為 NULL 被解釋為 0。

3. nullptr

為了解決 0NULL 的這些問題,C++11 引入了新的關鍵字 nullptr,這是一個明確的空指針類型,可以確保它只能用于指針上下文中。

int* p1 = nullptr;  // p1 是空指針

0NULL 不同,nullptr 是類型安全的,不能被隱式轉換為其他類型(如整型)。它不會產生函數重載歧義問題,因此推薦在C++11及之后的代碼中使用 nullptr

#include <iostream>void Fun(int p) {std::cout << "Fun(int)" << std::endl;
}void Fun(int* p) {std::cout << "Fun(int*)" << std::endl;
}int main() {Fun(nullptr);  // 明確調用 Fun(int*)
}

總結?

雖然他們三者區別并不大,但是,在一些特殊情況還是需要進行區分使用的。

  • 0:C/C++98中,既可表示整數值,也可表示空指針,但可能產生混淆。
  • NULL:通過宏定義來表示空指針,雖然提高了可讀性,但依然可能與整型 0 混淆。
  • nullptr:C++11引入,明確表示空指針,解決了 0NULL 的問題,推薦使用。

在現代C++中,優先使用 nullptr 來表示空指針,確保代碼更安全和清晰。

共勉

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

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

相關文章

【Numpy核心編程攻略:Python數據處理、分析詳解與科學計算】2.1 NumPy高級索引:布爾型與花式索引的底層原理

2.1 NumPy高級索引&#xff1a;布爾型與花式索引的底層原理 目錄 #mermaid-svg-NpcC75NxxU2mkB3V {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-NpcC75NxxU2mkB3V .error-icon{fill:#552222;}#mermaid-svg-NpcC75…

云原生(五十二) | DataGrip軟件使用

文章目錄 DataGrip軟件使用 一、DataGrip基本使用 二、軟件界面介紹 三、附件文件夾到項目中 四、DataGrip設置 五、SQL執行快捷鍵 DataGrip軟件使用 一、DataGrip基本使用 1. 軟件界面介紹 2. 附加文件夾到項目中【重要】 3. DataGrip配置 快捷鍵使用&#xff1a;C…

【Elasticsearch】match_bool_prefix 查詢 vs match_phrase_prefix 查詢

Match Bool Prefix Query vs. Match Phrase Prefix Query 在 Elasticsearch 中&#xff0c;match_bool_prefix 查詢和 match_phrase_prefix 查詢雖然都支持前綴匹配&#xff0c;但它們的行為和用途有所不同。以下是它們之間的主要區別&#xff1a; 1. match_bool_prefix 查詢…

算法基礎——存儲

引入 基礎理論的進步&#xff0c;是推動技術實現重大突破&#xff0c;促使相關領域的技術達成跨越式發展的核心。 在發展日新月異的大數據領域&#xff0c;基礎理論的核心無疑是算法。不管是技術設計&#xff0c;還是工程實踐&#xff0c;都必須仰仗相關算法的支持&#xff0…

正則表達式入門

入門 1、提取文章中所有的英文單詞 //1&#xff0e;先創建一個Pattern對象&#xff0c;模式對象&#xff0c;可以理解成就是一個正則表達式對象 Pattern pattern Pattern.compile("[a-zA-Z]"); //2&#xff0e;創建一個匹配器對象 //理解:就是 matcher匹配器按照p…

分布式架構中的事務管理:需要了解的常見解決方案

前言 在現代互聯網應用中&#xff0c;分布式架構越來越常見。隨著系統規模的擴大&#xff0c;越來越多的業務和數據被分布到不同的服務和數據庫中。雖然分布式架構帶來了諸多優勢&#xff0c;但也引入了一個新的問題&#xff1a;分布式事務。 一、什么是分布式事務&#xff1…

《TCP 網絡編程實戰:開發流程、緩沖區原理、三次握手與四次揮手》

一、 TCP 網絡應用程序開發流程 學習目標 能夠知道TCP客戶端程序的開發流程1. TCP 網絡應用程序開發流程的介紹 TCP 網絡應用程序開發分為: TCP 客戶端程序開發TCP 服務端程序開發說明: 客戶端程序是指運行在用戶設備上的程序 服務端程序是指運行在服務器設備上的程序,專門…

新年新挑戰:如何用LabVIEW開發跨平臺應用

新的一年往往伴隨著各種新的項目需求&#xff0c;而跨平臺應用開發無疑是當前備受矚目的發展趨勢。在眾多開發工具中&#xff0c;LabVIEW 以其獨特的圖形化編程方式和強大的功能&#xff0c;為開發跨平臺應用提供了有效的途徑。本文將深入探討如何運用 LabVIEW 開發能夠在不同操…

C 語言實現計算一年中指定日期是第幾天?題】

引言 在編程的世界里&#xff0c;處理日期和時間相關的問題是非常常見的。比如在日歷應用、任務管理系統、數據分析等場景中&#xff0c;經常需要計算某個日期在一年中是第幾天。本文將詳細介紹如何使用 C 語言來實現這一功能&#xff0c;通過分析代碼的結構、邏輯以及可能存在…

rsync安裝與使用-linux015

使用 rsync 可以非常高效地將文件或目錄從一個服務器傳輸到另一個服務器。 能力&#xff1a; 支持 64 位文件、64 位 inode、64 位時間戳、64 位長整型支持套接字對、符號鏈接、符號鏈接時間、硬鏈接、硬鏈接特殊文件、硬鏈接符號鏈接支持 IPv6、訪問時間&#xff08;atimes&…

UE5.3 C++ CDO的初步理解

一.UObject UObject是所有對象的基類&#xff0c;往上還有UObjectBaseUtility。 注釋&#xff1a;所有虛幻引擎對象的基類。對象的類型由基于 UClass 類來定義。 這為創建和使用UObject的對象提供了 函數&#xff0c;并且提供了應在子類中重寫的虛函數。 /** * The base cla…

Pandas基礎06(異常值的檢測與過濾/抽樣/常用聚合函數/數據聚合)

Pandas基礎06 異常值的檢測與過濾 在數據分析中&#xff0c;異常值&#xff08;Outliers&#xff09;是指與其他數據點顯著不同的值。這些值可能由于數據錄入錯誤、設備故障或極端情況而產生&#xff0c;因此在進行數據分析之前&#xff0c;需要對其進行檢測與過濾。本文將介紹…

【PyTorch】4.張量拼接操作

個人主頁&#xff1a;Icomi 在深度學習蓬勃發展的當下&#xff0c;PyTorch 是不可或缺的工具。它作為強大的深度學習框架&#xff0c;為構建和訓練神經網絡提供了高效且靈活的平臺。神經網絡作為人工智能的核心技術&#xff0c;能夠處理復雜的數據模式。通過 PyTorch&#xff0…

jstat命令詳解

jstat 用于監視虛擬機運行時狀態信息的命令&#xff0c;它可以顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT 編譯等運行數據。 命令的使用格式如下。 jstat [option] LVMID [interval] [count]各個參數詳解&#xff1a; option&#xff1a;操作參數LVMID&#xff1a;本…

App.Current.Services.GetService<UserView>()無限循環

代碼無線循環 public partial class UserView : UserControl{public UserView(){InitializeComponent();InitData();}private void InitData(){DataContext App.Current.Services.GetService<UserView>();}} } DataContext App.Current.Services.GetService<User…

(動態規劃路徑基礎 最小路徑和)leetcode 64

視頻教程 1.初始化dp數組&#xff0c;初始化邊界 2、從[1行到n-1行][1列到m-1列]依次賦值 #include<vector> #include<algorithm> #include <iostream>using namespace std; int main() {vector<vector<int>> grid { {1,3,1},{1,5,1},{4,2,1}…

松靈機器人 scout ros2 驅動 安裝

必須使用 ubuntu22 必須使用 鏈接的humble版本 #打開can 口 sudo modprobe gs_usbsudo ip link set can0 up type can bitrate 500000sudo ip link set can0 up type can bitrate 500000sudo apt install can-utilscandump can0mkdir -p ~/ros2_ws/srccd ~/ros2_ws/src git cl…

pytorch基于GloVe實現的詞嵌入

PyTorch 實現 GloVe&#xff08;Global Vectors for Word Representation&#xff09; 的完整代碼&#xff0c;使用 中文語料 進行訓練&#xff0c;包括 共現矩陣構建、模型定義、訓練和測試。 1. GloVe 介紹 基于詞的共現信息&#xff08;不像 Word2Vec 使用滑動窗口預測&…

C++ 堆棧分配的區別

這兩種聲明方式有什么區別 1.使用 new 關鍵字動態分配內存 動態分配&#xff1a;使用 new 關鍵字會在堆&#xff08;heap&#xff09;上分配內存&#xff0c;并返回一個指向該內存位置的指針。生命周期&#xff1a;對象的生命周期不會隨著聲明它的作用域結束而結束&#xff0…

深入解析 Linux 內核中的頁面錯誤處理機制

在現代操作系統中,頁面錯誤(Page Fault)是內存管理的重要組成部分。當程序試圖訪問未映射到物理內存的虛擬內存地址時,CPU 會觸發頁面錯誤異常。Linux 內核通過一系列復雜的機制來處理這些異常,確保系統的穩定性和性能。本文將深入解析 Linux 內核中處理頁面錯誤的核心代碼…