【C语言进阶深度学习记录】九 C语言中const的详细分析
生活随笔
收集整理的這篇文章主要介紹了
【C语言进阶深度学习记录】九 C语言中const的详细分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 const的分析
- 2 const本質的分析實驗
- 2.1 代碼案例分析
- 3 const修飾函數參數和返回值時的情況
- 3.1 代碼案例分析
- 4 總結
1 const的分析
不管是C語言還是C++語言,const都是一個非常重要的關鍵字。今天這篇文章著重學習記錄C語言中的const。C++語言中稍有不同。
在C語言中:
- const修飾的變量是只讀的,本質上還是變量。注意,不是常量。
- const修飾的變量如果是局部非靜態變量,則該變量存儲在棧上
- const修飾的變量如果是全局變量,則該變量一定是存儲在全局的數據區(.data)
- const修飾的變量,在程序編譯期就得出了相應的屬性,在運行期間該const關鍵字沒有作用
注意:const修飾的變量,不是真正的常量。它只是告訴編譯器它修飾的變量不能出現在賦值符號的左邊。后面我們會知道,const修飾的局部變量是可以通過指針改變的,但是const修飾的全局變量是不可以改變的(當然,這是現代C編譯器,標準C編譯器編譯的,還是可以修改。后面會有說明)
在現代C語言編譯器中,修改const修飾的變量會導致程序段錯誤。程序崩潰。因為現代C語言編譯器會將const修飾的變量儲存在只讀存儲區(.rodata)。
但是在標準C語言編譯器中,不會將const修飾的變量儲存在只讀存儲區。而是儲存在可修改的全局數據區(.data),所以它的值依然可以改變。只要通過指針找到它的地址,就可以改變它的值。
- 比如下面的代碼,放到比較老的BCC編譯器中編譯與在vs2017中編譯效果肯定是不同的。由于沒有安裝BCC編譯器且代碼邏輯比較簡單,實驗部分,讀者可以自己做實驗:
2 const本質的分析實驗
其實上面的內容就已經說了const的本質。
- C語言中的const使得變量具有只讀屬性
- 現代C語言編譯器中,將const修飾的具有全局生命周期的變量(包括全局變量和局部靜態變量)儲存在.rodata區。
const 不能定義真正意義上的常量
2.1 代碼案例分析
- 9-2-lyy.c
- 在現代C語言編譯器中進行編譯運行嗎,上述代碼是可以運行成功的。證明了局部const變量是可以通過指針修改的。
- 同時上述代碼的第17和19行,如果不注釋掉,程序的就無法運行,會產生段錯誤。這也說明了全局變量和局部靜態變量如果被const修飾的話,編譯器會將其修飾的變量放到.rodata區,這個區的內容是不允許被改變的,通過指針也無法改變。
3 const修飾函數參數和返回值時的情況
- const修飾函數參數,表示在函數體內不希望修改該參數的值
- const修飾函數的返回值,表示返回值不可改變。多用于函數返回值為指針的情形。
注意:C語言中的字符串字面量,存儲于.rodata區,在程序中需要使用const char* 指針修飾字符串。
如:
3.1 代碼案例分析
- 代碼9-3-lyy.c
- 上述代碼編譯后(編譯有警告),運行會產生錯誤,因為pc所指向的內存為.rodata區。不能修改.rodata區里面的內容。第16行會導致程序產生段錯誤。
- 當然,第5行注釋的代碼,會導致程序編譯出錯。
4 總結
- const使得變量具有只讀屬性
- const不能定義真正意義上的常量
- const將具有全局生命周期的變量(包括const全局變量,const局部靜態變量),儲存在具有只讀屬性的.rodata區中。不能通過指針法修改該區域中的變量
- 標準C編譯器與現代C編譯器稍有不同,標準C編譯器不會將const修飾的具有全局生命周期的變量儲存在.rodata區中,所以可以通過指針修改該變量。
一般來說,我們使用的都是現代C編譯器
總結
以上是生活随笔為你收集整理的【C语言进阶深度学习记录】九 C语言中const的详细分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GmSSL3.0 在Android上的命
- 下一篇: spss练习数据_SPSS篇——如何在成