C++ void 指針和指針類型轉(zhuǎn)換方法
?? 前言:為什么要指針轉(zhuǎn)換?
想象一下,內(nèi)存就像一個(gè)大倉庫,不同類型的變量就像不同形狀的箱子。指針就是指向這些箱子的標(biāo)簽。有時(shí)候我們需要用不同的方式看待同一個(gè)箱子,這就需要進(jìn)行指針類型轉(zhuǎn)換。
第一章:為什么需要不同類型的指針?
int*:告訴程序這個(gè)地址里存放的是整數(shù)char*:告訴程序這個(gè)地址里存放的是字符void*:通用的地址,但不告訴程序里面是什么類型
就像不同類型的箱子需要不同的工具打開,不同類型的指針決定了如何解釋內(nèi)存中的數(shù)據(jù)。
第二章:解析
2.1 動(dòng)態(tài)內(nèi)存分配:malloc和free
void* ptr1 = malloc(1024); // 申請1024字節(jié)的內(nèi)存 free(ptr1); // 釋放這塊內(nèi)存
核心概念:
malloc:從內(nèi)存堆中申請一塊空間,返回void*free:釋放之前申請的內(nèi)存void*:萬能指針,可以指向任何類型的數(shù)據(jù)
現(xiàn)實(shí)類比:
malloc= 向倉庫管理員要一個(gè)箱子free= 用完箱子后歸還void*= 只知道箱子編號,不知道里面裝什么
重要提醒:在C++中,更推薦使用new/delete,因?yàn)樗鼈兪穷愋桶踩摹?/p>
2.2 將void*轉(zhuǎn)換為具體類型
int num = 1; void* ptr = # // 將int的地址存入void* int* ptr2 = static_cast<int*>(ptr); // 使用static_cast轉(zhuǎn)換 int* ptr3 = (int*)ptr; // 使用C風(fēng)格轉(zhuǎn)換
轉(zhuǎn)換方式對比:
| 轉(zhuǎn)換方式 | 寫法 | 特點(diǎn) | 安全性 |
|---|---|---|---|
| static_cast | static_cast<int*>(ptr) | 編譯時(shí)檢查 | ??? |
| C風(fēng)格轉(zhuǎn)換 | (int*)ptr | 簡單粗暴 | ? |
為什么要有兩種方式?
static_cast就像有安檢的通道,會進(jìn)行類型檢查;C風(fēng)格轉(zhuǎn)換就像翻墻,什么都能做,但也容易出事故。
最佳實(shí)踐:優(yōu)先使用static_cast,讓編譯器幫你檢查類型安全。
2.3 常量指針的轉(zhuǎn)換
const int* cptr1 = new int[1024]; // 指向常量的指針 // int* ptr4 = static_cast<int*>(cptr1); // ? 編譯錯(cuò)誤! int* ptr4 = (int*)(cptr1); // ? C風(fēng)格轉(zhuǎn)換(危險(xiǎn)) int* ptr6 = const_cast<int*>(cptr1); // ? const_cast(專門去除const)
理解const指針:
const int* p1; // 指向常量的指針:不能通過p1修改指向的內(nèi)容 int* const p2; // 常量指針:p2本身不能指向別處 const int* const p3; // 兩者都不能修改
const_cast的作用:
- 專門用來添加或移除const/volatile屬性
- 其他轉(zhuǎn)換方式不能修改const屬性
- 使用時(shí)必須非常小心!
危險(xiǎn)警告:
const int value = 100; const int* p = &value; int* q = const_cast<int*>(p); *q = 200; // ? 未定義行為!value本來是常量
如果原始數(shù)據(jù)就是const的,通過const_cast修改它會導(dǎo)致程序崩潰或不可預(yù)測的結(jié)果。
2.4 不同類型指針間的轉(zhuǎn)換
unsigned char* ucptr = new unsigned char[1024]; // 無符號字符數(shù)組 // int* ptr5 = static_cast<int*>(ucptr); // ? 編譯錯(cuò)誤! auto ptr5 = (int*)ucptr; // ? C風(fēng)格轉(zhuǎn)換 auto ptr7 = reinterpret_cast<int*>(ucptr); // ? reinterpret_cast
reinterpret_cast:最底層的轉(zhuǎn)換
reinterpret_cast<int*>(ucptr);
特點(diǎn):
- 不改變內(nèi)存中的二進(jìn)制數(shù)據(jù)
- 只是改變編譯器解釋這些數(shù)據(jù)的方式
- 最危險(xiǎn),但有時(shí)不得不使用(如硬件編程)
現(xiàn)實(shí)類比:把一疊英文文件強(qiáng)行當(dāng)成中文文件來讀,雖然地址沒變,但解讀出來的內(nèi)容可能完全錯(cuò)誤。
2.5 釋放內(nèi)存
delete []ucptr; // 釋放數(shù)組內(nèi)存 delete []cptr1; // 注意:即使是const指針,也要用delete[]
重要規(guī)則:
new對應(yīng)deletenew[]對應(yīng)delete[]- 配錯(cuò)對會導(dǎo)致未定義行為!
第三章:轉(zhuǎn)換方式總結(jié)表
| 轉(zhuǎn)換類型 | static_cast | const_cast | reinterpret_cast | C風(fēng)格轉(zhuǎn)換 |
|---|---|---|---|---|
| 相關(guān)類型轉(zhuǎn)換 | ? | ? | ? | ? |
| 去除const | ? | ? | ? | ? |
| 無關(guān)指針轉(zhuǎn)換 | ? | ? | ? | ? |
| 安全性 | 高 | 中 | 低 | 極低 |
| 使用頻率 | 高 | 低 | 極低 | 避免 |
第四章:最佳實(shí)踐指南
?? 避免做的事:
不要隨意去除const
// 不好的做法 const char* msg = "Hello"; char* p = const_cast<char*>(msg); p[0] = 'h'; // 危險(xiǎn)!
不要在不同類型指針間隨意轉(zhuǎn)換
// 不好的做法 float f = 3.14; int* p = reinterpret_cast<int*>(&f); // 解釋方式完全錯(cuò)誤
不要混合使用new/delete和malloc/free
int* p = new int; free(p); // ? 錯(cuò)誤!必須用delete
? 推薦的做法:
優(yōu)先使用static_cast
double d = 3.14; int i = static_cast<int>(d); // 數(shù)值類型轉(zhuǎn)換
使用智能指針管理內(nèi)存
#include <memory> std::unique_ptr<int[]> ptr(new int[1024]); // 自動(dòng)釋放
盡量保持類型一致
// 好的做法 int* arr = new int[100]; int* p = arr; // 類型一致,無需轉(zhuǎn)換
第五章:練習(xí)
練習(xí)1:找出問題
const int num = 10; const int* p1 = # int* p2 = static_cast<int*>(p1); // 這行有什么問題?
static _cast不能移除const
練習(xí)2:正確的轉(zhuǎn)換
void* ptr = malloc(sizeof(int)); // 如何正確地將ptr轉(zhuǎn)換為int*并賦值5?
int* intPtr = static_cast<int*>(ptr); // 轉(zhuǎn)換為int*
*intPtr = 5;
練習(xí)3:內(nèi)存管理
int* arr = new int[100]; // 如何正確釋放這塊內(nèi)存?
delete[] arr;
第六章:常見誤區(qū)解答
Q1:什么時(shí)候必須用reinterpret_cast?
A:硬件編程、系統(tǒng)調(diào)用、序列化等底層操作,但通常不超過代碼的5%。
Q2:C風(fēng)格轉(zhuǎn)換有什么好處?
A:寫法簡單,但弊大于利,建議不用。
Q3:為什么new/delete比malloc/free好?
A:new會調(diào)用構(gòu)造函數(shù),delete會調(diào)用析構(gòu)函數(shù),更符合C++面向?qū)ο蟮乃枷搿?/p>
Q4:const_cast真的有實(shí)際用途嗎?
A:有的,比如調(diào)用舊版C庫函數(shù)(它們可能沒加const),但要確保原始對象不是const。
到此這篇關(guān)于C++ void 指針和指針類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++ void 指針類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++四種類型轉(zhuǎn)換全解
- C++特殊類設(shè)計(jì)與類型轉(zhuǎn)換詳細(xì)代碼示例
- C++中不同類型默認(rèn)轉(zhuǎn)換的規(guī)則和機(jī)制詳解
- C++中五種類型轉(zhuǎn)換的深度對比與實(shí)踐指南
- C++強(qiáng)制類型轉(zhuǎn)換詳細(xì)示例代碼
- C++特殊類設(shè)計(jì)及類型轉(zhuǎn)換舉例詳解
- C++迭代器和顯示類型轉(zhuǎn)換方式
- 一文帶你探索C++中類型轉(zhuǎn)換的奧秘
- 詳解C++中的四種類型轉(zhuǎn)換運(yùn)算符
- C++類型轉(zhuǎn)換通用接口設(shè)計(jì)實(shí)現(xiàn)
相關(guān)文章
C++控制權(quán)限關(guān)鍵字protected
這篇文章主要介紹了C++控制權(quán)限關(guān)鍵字protected,protected和private類似,而對于派生類來說,protected與public類似,下面來一起倆姐更多詳細(xì)內(nèi)容吧,需要的小伙伴可以參考一下2022-01-01
C++?list常用接口和模擬實(shí)現(xiàn)實(shí)例代碼
C++中l(wèi)ist容器底層實(shí)現(xiàn)是使用帶頭雙向循環(huán)鏈表的結(jié)構(gòu),通過指針指向前一個(gè)和后一個(gè)節(jié)點(diǎn),它也具有雙向鏈表的優(yōu)缺點(diǎn),下面給大家介紹C++?list常用接口和模擬實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2025-04-04
C++?sort()與stable_sort()使用指北(附示例代碼)
這篇文章主要介紹了C++?sort()與stable_sort()使用的相關(guān)資料,std::sort()和std::stable_sort()都是C++標(biāo)準(zhǔn)庫中的排序算法,文中通過代碼將用法介紹的非常詳細(xì),需要的朋友可以參考下2025-12-12
FFmpeg實(shí)現(xiàn)將編碼后數(shù)據(jù)保存成mp4
這篇文章主要為大家詳細(xì)介紹了FFmpeg如何實(shí)現(xiàn)將編碼后數(shù)據(jù)保存成mp4,即從內(nèi)存塊中獲取原始數(shù)據(jù),然后依次進(jìn)行解碼、編碼、最后保存成mp4視頻文件,感興趣的可以了解一下2023-08-08

