const關鍵字(摘抄&總結)
4.3.4 const關鍵字與指標
4.3.4.1 const修飾指標的4種形式
(1)const關鍵字,在C語言用來修飾變數,表示這個變數是常量
(2)const修飾指標有4種形式,區分清楚這4種即可全部理解const和指標
第一種:const int *p; //p本身不是const的,而p指向的變數是const的
第二種:int const *p; //p本身不是const的,而p指向的變數是const的
第三種:int * const p; //p本身是const的,而p指向的變數不是const的
第四種:const int * const p;//p本身是const的,而p指向的變數也是const的
(3)關於指標變數的理解,主要設計兩個變數:第一個是指標變數p本身,第二個是p指向的那個變數(*p)。一個const關鍵字只能修飾一個變數,所以弄清楚這四個表示式的關鍵就是搞清楚const放在某個位置是修飾誰的。
4.3.4.2 const修飾的變數真的不能改嗎?
(1)課堂練習說明:const變數可以修改(前提是gcc環境、VC6.0 環境)
(2)在某些微控制器環境下,const變數是不可以修改的。
const變數到底能不能被修改,取決於具體的環境,C語言本身並沒有完全一直的要求。
(3)在gcc環境,const是通過編譯器在編譯時執行檢查來確保實現的(也就是說const型別的變數不能改是編譯錯誤,不是執行錯誤)所以只要騙過編譯器,就可以修改const定義的常量,而執行時不會報錯。
(4)更深一層的原因,是因為gcc把const型別的變數也放在了data段,其實和普通的全域性變數放在data段是一樣的,只是通過編譯器認定的這個變數是const的,執行時並沒有標記const標誌,所以只要騙過編譯器就可以修改了。
4.3.4.3 const究竟應該怎麼用
(1)const是在編譯器中實現的,編譯時檢查。並非不能騙過。所以在C語言中使用const就好像是一種道德約束,所以大家使用const時更多的是傳遞一種資訊,就是告訴編譯器、也告訴讀程式的人,這個變數是不應該也不必被修改的。
4.3.10 輸入型引數與輸出型引數
4.3.10.1 函式為什麼需要形參與返回值
(1)函式名是一個符號,表示整個函式程式碼段的首地址,實質是一個指標常量,所以在程式中使用到函式名時都是當地址用的,用來呼叫這個函式的。
(2)函式體是函式的關鍵,由一對{}括起來,包含很多句程式碼,函式體就是函式實際做的工作。
(3)形參列表和返回值。形參是函式的輸入部分,返回值是函式的輸出部分。對函式的最好理解就是把函式看成一個加工機器,形參列表就是這個機器的原材料輸入端;而返回值就是機器的成品輸出端。
(4)其實沒有形參列表和返回值,函式也能對資料加工,用全域性變數即可。
(5)用全域性變數來傳參和用函式列表返回值來傳參各有特點,在實踐中都有使用。總的來說函式傳參用的比較多,因為這樣可以實現模組化程式設計,而C語言中也是儘量減少使用全域性變數。
(6)全域性變數傳參最大的好處就是省略了函式傳參的開銷,所以效率要高一些;但是實戰中用的最多的還是傳參,如果傳參很多開銷很大,通常做法是把很多引數打包成一個結構體,然後傳結構體變數指標進去。
4.3.10.2 函式傳參中使用const指標
(1)const一般用在函式列表中,用法是const int *p(意義是指標變數p本身可以改變,而p指向的變數是不可以改變的)
(2)const用來修飾指標做函式傳參,作用就在於宣告在函式內部不會改變這個指標所指向的內容,所以在給函式傳一個不可改變的指標(char *p ="linux"這種)不會觸發錯誤;而未宣告為const的指標的函式,你給他傳一個不可更改的指標的時候就要小心了。
4.3.10.3 函式需要向外部返回多個值時怎麼辦?
(1)一般來說,函式的輸入部分就是函式引數,輸出部分就是返回值。問題是函式的引數可以有很多個,而返回值只能有1個。這就造成了無法讓一個函式返回多個值。
(2)現實程式設計中,一個函式需要多個返回值是非常普遍的,因此完全依賴於返回值是不靠譜的,通常的做法是用引數來返回(在典型的Linux風格中,返回值不是用來返回結果的,而是用來返回0或者負數用來表示程式執行結果是對還是錯,是成功還是失敗)
(3)普遍做法,程式設計中函式的輸入和輸出都是靠函式引數的,返回值只是用來表示函式執行的結果。如果這個函式用來做輸入的,就叫做輸入型引數;如果這個引數的目的是用來做輸出的,就叫做輸出型引數。
(4)輸出型引數就是用來讓函式把內部引數輸出到函式外部的。
4.3.10.4 總結
值傳遞:輸入型引數
地址傳遞:輸入和輸出型引數都可以。
(1)看到一個函式原型,怎麼一眼看出那個函式做輸入那個做輸出?
函式傳參如果傳的是普通變數(值)那肯定是輸入型引數,如果傳指標(地址)就有2種可能性,為了區別,經常做法就是:如果這個引數是做輸入的(通常做輸入的在函式內部只需要讀取這個引數而不需要改變它)就在指標前面加const修飾;如果函式引數是指標變數並且沒有加const修飾,那麼表示這個引數用來做輸出型引數的。
其他參考: