1. const 修飾變量
1.1 const修飾變量
變量被const修飾時,變量此時為常變量,本質為常量,語法上不可被修改,但是如果此時需要修改變量值,可以通過指針的方式修改。
雖然此時通過指針的方式確實修改了變量的值,但這并不符合const修飾變量的語法,為了防止const修飾的變量被修改,可以修飾指針變量,防止const修飾變量被修改。
1.2 const 修飾指針變量
const在*pb前表示pb指向的對象不可被修改,此時就很好的保護const修飾的變量值,上述const修飾的指針變量還可以寫成:int const *pb,語法上也是支持的。此時const修飾的指針變量可以防止指向的對象被修改,但是指針變量本身是可以被修改的。
原本指針變量是為了存放b的地址,指針變量本身未被修飾,存放變量c的地址后導致指針變量指向其它內存空間,為了防止指針變量指向其它內存空間,使用const修飾指針變量,修飾后的指針變量存放的地址不可被修改。
結論:const修飾指針變量的時候
const如果放在*的左邊,修飾的是指針指向的內容,保證指針指向的內容不能通過指針來改變。 但是指針變量本?的內容可變。
const如果放在*的右邊,修飾的是指針變量本?,保證了指針變量的內容不能修改,但是指針指向的內容,可以通過指針改變。
2. 野指針
野指針指向的內存空間是隨機的,不可知的,沒有明確限制的。
2.1 野指針成因
2.1.1 指針未初始化
2.1.2. 指針越界訪問
2.1.3 函數返回局部變量的指針
在vs2022環境下多次輸出的結果:多次輸出的均為隨機值
2.2 如何規避野指針
2.2.1 初始化指針
需要使用指針是,要明確指針存放的地址,對其進行初始化,當暫時不明確指針存放的地址,可以將其初始化為空指針NULL,c語言中空指針為void*0。
2.2.2 ??指針越界
需要訪問數組元素時,可以求出元素的個數,利用for循環進行訪問,防止越界
2.2.3?指針變量不再使?時,及時置NULL,指針使?之前檢查有效性
3. assert 斷?
assert.h 頭?件定義了宏 assert() ,?于在運?時確保程序符合指定條件,如果不符合,就報錯終?運?,這個宏常常被稱為“斷?”。
assert在c語言庫函數網站的詳細介紹:assert - C++ Reference
assert不僅可以用于判斷指針,還可以用于表達式的判斷:
按F10啟動調試,執行第二條assert語句時,系統報錯:窗口輸出具體的報錯原因
斷言失敗:Assertion failed: *pa>*pb,說明assert括號內的表達式為假,執行斷言。
4. 指針的使?和傳址調?
4.1 模擬strlen函數的實現
4.2 傳值調?和傳址調?
實現一個函數交換兩個數
第一次交換并沒有成功交換,輸出的結果還是num1=10? num2=20,這是因為Swap1函數接收的函數參數時,開辟了新的內存空間進行存num1和num2,改變的為x和y形參的的值,,函數棧幀銷毀時,x和y的值并不能存儲返回,因此x和y只是實參的一份臨時拷貝,改變形參并不一定改變實參;
第二次交換交換成功,將num1和 num2的地址作為參數傳參時,接收的函數參數改變時,是通過地址指向的位置改變,x指向num1的地址,y指向num2的位置,此時改變形參可以改變實參。
傳址調?,可以讓函數和主調函數之間建?真正的聯系,在函數內部可以修改主調函數中的變量;函數中只是需要主調函數中的變量值來實現計算,就可以采?傳值調?。如果函數內部要修改主調函數中的變量的值,就需要傳址調?。