C++ 常量指針與指針常量的實(shí)現(xiàn)示例
?? 前言:為什么要區(qū)分這兩個(gè)概念?
很多C++初學(xué)者看到"常量指針"和"指針常量"這兩個(gè)詞就頭暈,因?yàn)樗鼈兲窳?!其?shí)區(qū)分它們有一個(gè)簡(jiǎn)單口訣:
“左定值,右定向”(const在*左邊,修飾的是指向的值;const在*右邊,修飾的是指針本身)
第一章:基礎(chǔ)概念圖解
1.1 指針的兩個(gè)屬性
每個(gè)指針都有兩個(gè)可以"恒定"的東西:
- 指針本身:指針變量存儲(chǔ)的地址(指向哪里)
- 指向的值:通過(guò)指針訪問(wèn)的數(shù)據(jù)
第二章:代碼解析
2.1 準(zhǔn)備一個(gè)常量
const int i1 = 100; // 定義一個(gè)常量整數(shù)
理解:
i1是一個(gè)常量,值為100- 一旦定義,不能通過(guò)任何方式修改
i1的值 - 這為后面的例子提供了一個(gè)"只讀"的數(shù)據(jù)源
2.2 常量指針(指向常量的指針)
const int* pi1 = &i1; // 指向常量的指針 // (*pi1)++; ? 指向的值不可修改
什么是常量指針?
常量指針 = 指針指向的值是常量,不能通過(guò)該指針修改
代碼分析:
const int*:const在*左邊,修飾的是int,表示"指向常量的指針"pi1指向i1(常量)- 嘗試
(*pi1)++會(huì)編譯錯(cuò)誤,因?yàn)椴荒苄薷闹赶虻闹?/li>
2.3 另一種寫法
int const* pi2 = &i1; // 同上,兩種寫法都表示常量指針 // (*pi2)++; ? 同樣不能修改
為什么有兩種寫法?
const int* p; // 方法1:const在類型前 int const* p; // 方法2:const在類型后
這兩種寫法完全等價(jià)! 都表示"指向const int的指針"
記憶技巧:
- 無(wú)論
const在int前面還是后面,只要它在*左邊,就是修飾指向的值 - 可以讀作:
const int*= “不能修改int的指針”
2.4 指針常量(常量指針)
int* const pi3 = new int; // 指針本身是常量 // pi3++; ? 指針本身不能修改 // pi3 = new int; ? 不能指向別處 *pi3 = 200; ? 指向的值可以修改 delete pi3; // 釋放內(nèi)存
什么是指針常量?
指針常量 = 指針本身是常量,不能改變指向,但可以修改指向的值
代碼分析:
int* const:const在*右邊,修飾的是指針本身pi3一旦初始化,就不能再指向其他地址- 但通過(guò)
pi3修改指向的值是允許的
2.5 指向常量的常量指針
const int* const pi4 = &i1; // 指向和值都不能修改 // pi4 = new int; ? 指針本身不能修改 // *pi4 = 300; ? 指向的值不能修改
最強(qiáng)限定組合!
這個(gè)聲明結(jié)合了前兩者的特點(diǎn):
- 第一個(gè)
const:指向的值是常量(在*左邊) - 第二個(gè)
const:指針本身是常量(在*右邊)
第三章:對(duì)比總結(jié)表
| 類型 | 聲明方式 | 口訣 | 能否修改指向 | 能否修改值 | 示例 |
|---|---|---|---|---|---|
| 常量指針 | const int* p 或 int const* p | 左定值 | ? 可改 | ? 不可改 | p = &b; ? |
| 指針常量 | int* const p | 右定向 | ? 不可改 | ? 可改 | *p = 10; ? |
| 雙重const | const int* const p | 都定 | ? 不可改 | ? 不可改 | 都不能改 |
第四章:記憶技巧大全
4.1 星號(hào)分割法
從*處把聲明分成左右兩部分:
const int * p // 左邊是const int,右邊是p int * const p // 左邊是int,右邊是const p
規(guī)則:
*左邊的內(nèi)容描述"指向的值"*右邊的內(nèi)容描述"指針本身"
4.2 英語(yǔ)閱讀法
從右往左讀:
const int* p:p is a pointer to const intint* const p:p is a const pointer to int
第五章:常見(jiàn)應(yīng)用場(chǎng)景
5.1 常量指針的應(yīng)用
場(chǎng)景:函數(shù)參數(shù)保護(hù)
void printArray(const int* arr, int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " "; // 只能讀取,不能修改
// arr[i] = 0; ? 編譯錯(cuò)誤,保護(hù)數(shù)組內(nèi)容
}
}
int data[] = {1, 2, 3, 4, 5};
printArray(data, 5); // 安全傳遞,確保data不會(huì)被修改
5.2 指針常量的應(yīng)用
場(chǎng)景:固定緩沖區(qū)地址
class Buffer {
int* const buffer; // 緩沖區(qū)地址固定
const int size; // 緩沖區(qū)大小固定
public:
Buffer(int s) : buffer(new int[s]), size(s) {}
void setValue(int index, int value) {
if (index < size) {
buffer[index] = value; // 可以修改內(nèi)容
}
}
~Buffer() { delete[] buffer; }
};
5.3 雙重const的應(yīng)用
場(chǎng)景:只讀配置項(xiàng)
class Config {
const char* const name; // 名稱既不能改指向,也不能改內(nèi)容
const int version; // 版本號(hào)常量
public:
Config(const char* n, int v) : name(n), version(v) {}
const char* getName() const { return name; }
int getVersion() const { return version; }
};
第六章:常見(jiàn)誤區(qū)與練習(xí)
誤區(qū)1:混淆聲明順序
const int* p; // 指向常量的指針 int const* p; // 也是指向常量的指針(容易誤以為是指針常量) int* const p; // 這是指針常量!
誤區(qū)2:以為const必須初始化
const int* p; // ? 可以,p可以先不指向任何東西 int* const p; // ? 錯(cuò)誤!指針常量必須初始化! int* const p = &x; // ? 正確,必須初始化
誤區(qū)3:通過(guò)轉(zhuǎn)換繞過(guò)const
const int value = 100; const int* p = &value; int* q = const_cast<int*>(p); // 危險(xiǎn)操作! *q = 200; // 未定義行為!value本來(lái)是常量
?? 動(dòng)手練習(xí)
練習(xí)1:識(shí)別類型
int a = 10; int b = 20; // 分別說(shuō)出下面這些指針的類型和特性 const int* p1 = &a; int* const p2 = &a; const int* const p3 = &a;
練習(xí)2:找出錯(cuò)誤
int num = 5; const int* ptr1 = # int* const ptr2 = # ptr1 = &b; // 這行有問(wèn)題嗎? *ptr1 = 10; // 這行有問(wèn)題嗎? ptr2 = &b; // 這行有問(wèn)題嗎? *ptr2 = 10; // 這行有問(wèn)題嗎?
練習(xí)3:補(bǔ)全代碼
void processData(__________ data, int size) {
// 函數(shù)需要保證不修改data指向的內(nèi)容
for (int i = 0; i < size; i++) {
cout << data[i] << " ";
}
}
// 應(yīng)該用什么類型作為參數(shù)?
答案
練習(xí)1答案:
p1:常量指針(指向的值不能改,但可以改指向)p2:指針常量(指向不能改,但可以改值)p3:雙重const(都不能改)
練習(xí)2答案:
ptr1 = &b; // ? 可以,p1是常量指針,可以改指向 *ptr1 = 10; // ? 不可以,p1指向的值是常量 ptr2 = &b; // ? 不可以,p2是指針常量,不能改指向 *ptr2 = 10; // ? 可以,p2指向的值可以修改
練習(xí)3答案:
void processData(const int* data, int size) // 使用常量指針
總結(jié):終極記憶法
| 聲明 | 讀法 | 能否改指向 | 能否改值 |
|---|---|---|---|
| const int* p | p是一個(gè)指向const int的指針 | ? | ? |
| int const* p | p是一個(gè)指向const int的指針 | ? | ? |
| int* const p | p是一個(gè)const指針,指向int | ? | ? |
| const int* const p | p是一個(gè)const指針,指向const int | ? | ? |
“const在左邊,值是常量;const在右邊,指針是常量”
到此這篇關(guān)于C++ 常量指針與指針常量的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)C++ 常量指針與指針常量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中快速排序和插入排序優(yōu)化的實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言中快速排序和插入排序優(yōu)化的實(shí)現(xiàn),包括雙向劃分快速排序方法的介紹,需要的朋友可以參考下2015-11-11
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單版三子棋
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單版三子棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C語(yǔ)言學(xué)習(xí)之關(guān)鍵字的示例詳解
關(guān)鍵字,這名字一聽(tīng),就很關(guān)鍵。而有些關(guān)鍵字,你可能不是很了解,更別談使用。所以,這篇文章將帶你見(jiàn)識(shí)常見(jiàn)的關(guān)鍵字,一起領(lǐng)略它們的風(fēng)采吧2022-10-10
貪吃蛇C語(yǔ)言代碼實(shí)現(xiàn)(難度可選)
這篇文章主要為大家詳細(xì)介紹了貪吃蛇C語(yǔ)言代碼實(shí)現(xiàn),游戲難度可供選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
C++標(biāo)準(zhǔn)庫(kù)(std)用法解讀
本文介紹了C++標(biāo)準(zhǔn)庫(kù)的主要組成部分及其使用方法,涵蓋命名空間、輸入輸出流、字符串處理、STL容器、算法、數(shù)值處理、函數(shù)對(duì)象與可調(diào)用對(duì)象、異常處理、時(shí)間日期、文件系統(tǒng)、線程支持和正則表達(dá)式等,示例代碼展示了如何使用這些功能2026-04-04
C++之a(chǎn)ssert推薦用法及注意事項(xiàng)
這篇文章主要給大家介紹了關(guān)于C++之a(chǎn)ssert推薦用法及注意事項(xiàng)的相關(guān)資料,assert 是一個(gè)預(yù)處理宏,用于在運(yùn)行時(shí)檢查表達(dá)式是否為真,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07

