網站首頁 編程語言 正文
我們要了解C++11新特性的nullptr,我們很有必要先了解一下C++11之前的程序員是怎么使用空指針的。
1.C++98中的空指針
我們知道,在良好的C/C++編程習慣中,聲明一個變量時最好給這個變量賦一個合適的初始值,否則就有可能出現不可預料的錯誤。
指針的危險性
在C++中創建指針時,計算機將分配用來存儲地址的內存,但不會分配用來存儲指針所指向的的數據的內存。為數據提供空間的是一個獨立的步驟,忽略這一步無疑是自找麻煩的,如下所示:
int* fellow;
*fellow = 1234;
fellow確實是一個指針,但它指向哪里呢?上述代碼沒有將地址賦給fellow,那么1234將被放置在哪個內存單元呢?我們并不知道。有fellow沒有被初始化,他可能有任何值。不管值是什么,程序都將他解釋為存儲1234的地址。但是如果fellow的值碰巧為1000,計算機將把數據放在地址1000上,即使這恰巧是程序代碼的地址,fellow指向的地方很可能并不是所要存儲的1234的地方,這種錯誤可能會導致一些最隱匿,最難以跟蹤的bug。
因此為了避免這個問題,我們都要給指針進行初始化。通常我們都是這樣來初始化指針的。
int main()
{
//空指針定義
int* p1 = NULL;
int* p2 = 0;
return 0;
}
實際上NULL是一個宏,我們在傳統的C頭文件(stddef.h)中就可以看到如下代碼:
可以看到, NULL 可能被定義為字面常量 0 ,或者被定義為無類型指針 (void*) 的常量 。不論采取何種定義,在使用空值的指針時,都不可避免的會遇到一些麻煩。 比如:下面這段代碼的輸出結果是什么?
void f(int)
{
cout << "f(int)" << endl;
}
void f(int*)
{
cout << "f(int*)" << endl;
}
int main()
{
//空指針定義
int* p1 = NULL;
int* p2 = 0;
f(0);
f(NULL);
return 0;
}
按照我們正常的想法f(0)應該進入void f (int),f(NULL)進入void f(int*),因此我們想要得到的結果是分別打印f(int)和f(int*)。我們來看運行結果是否和我們所想的一樣。
我們發現運行結果和我們所想存在出入,這是為什么?
這是因為程序本意是想通過f(NULL)調用指針版本的f(int*)函數,但是由于NULL被宏定義成了0,在預處理階段,NULL已經被宏替換成了0,因此f(NULL)函數就已經被替換成了f(0),因此我們才會得到兩個相同的打印結果。
在 C++98 中,字面常量 0 既可以是一個整形數字,也可以是無類型的指針 (void*) 常量,但是編譯器默認情況下將其看成是一個整形常量,如果要將其按照指針方式來使用,必須對其進行強轉(void *)0 。
2.C++11中的空指針
為了避免上述這個問題,C++11引入了nullptr關鍵字來表示指針空值。
int main()
{
//空指針定義
int* p1 = NULL;
int* p2 = 0;
//推薦
int* p3 = nullptr;
f(0);
f(NULL);
f(nullptr);
return 0;
}
因此我們再次傳入nullptr,看看他的結果是什么?
此時我們發現nullptr解決了這個問題。
注意:
1. 在使用 nullptr 表示指針空值時,不需要包含頭文件,因為 nullptr 是 C++11 作為新關鍵字引入的 。
2. 在 C++11 中, sizeof(nullptr) 與 sizeof((void*)0) 所占的字節數相同。 在32位機器下大小為4,在64位下大小為8。
3. 為了提高代碼的健壯性,在后續表示指針空值時建議最好使用 nullptr 。
結論:nullptr是對NULL的一個升級,因此在以后的初始化空指針時,建議大家使用nullptr。
原文鏈接:https://blog.csdn.net/qq_58325487/article/details/124770477
相關推薦
- 2022-09-08 pandas庫中to_datetime()方法的使用解析_python
- 2022-10-12 Python數據分析之使用scikit-learn構建模型_python
- 2023-01-01 C語言之如何求三次方根_C 語言
- 2022-01-18 django中ajax發送post請求報403錯誤csrf禁止,解決只需三步
- 2023-02-18 Framework中實現OC和Swift的混編方案_IOS
- 2022-05-25 ASP.NET?MVC+EF實現異步增刪改查_實用技巧
- 2022-08-26 go-micro開發RPC服務以及運行原理介紹_Golang
- 2024-01-27 解決“該項目不在請確認該項目位置,然后重試” 文件無法刪除問題
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支