C語(yǔ)言詳細(xì)分析講解關(guān)鍵字const與volatile的用法
一、const 只讀變量
- const 修飾的變量是只讀的,本質(zhì)還是變量
- const 修飾的局部變量在棧上分配空間
- const 修飾的全局變量在全局?jǐn)?shù)據(jù)區(qū)分配空間
- const 只在編譯期有用,在運(yùn)行期無(wú)用
const 修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現(xiàn)在賦值符號(hào)的左邊。
二、const 全局變量的分歧
在現(xiàn)代C語(yǔ)言編譯器中,修改 const 全局變量將導(dǎo)致程序崩潰。
注意:標(biāo)準(zhǔn)C語(yǔ)言編譯器不會(huì)將 cons t修飾的全局變量存儲(chǔ)于只讀存儲(chǔ)區(qū)中,而是存儲(chǔ)于可修改的全局?jǐn)?shù)據(jù)區(qū),其值依然可以改變。
下面看一段代碼:
#include <stdio.h> const int g_cc = 2; int main() { const int cc = 1; int* p = (int*)&cc; printf("cc = %d\n", cc); *p = 3; printf("cc = %d\n", cc); p = (int*)&g_cc; printf("g_cc = %d\n", g_cc); *p = 4; printf("g_cc = %d\n", g_cc); return 0; }
下面為輸出結(jié)果:
上面代碼說(shuō)明 const 修飾的局部變量可以通過(guò)指針修改里面的值,但是 const 修飾的全局變量則不能通過(guò)指針來(lái)修改里面的值,會(huì)發(fā)生段錯(cuò)誤。
三、const 的本質(zhì)
- C 語(yǔ)言中的 const 使得變量具有只讀屬性
- 現(xiàn)代 C 編譯器中的 const 將具有全局生命周期的變量存儲(chǔ)于只讀存儲(chǔ)區(qū)(staic 修飾的變量也有全局生命周期,所以用 const 修飾后也存儲(chǔ)于只讀存儲(chǔ)區(qū))
- const 不能定義真正意義上的常量
下面看一段 const 本質(zhì)分析的代碼:
#include <stdio.h> const int g_array[5] = {0}; void modify(int* p, int v) { *p = v; } int main() { int const i = 0; const static int j = 0; int const array[5] = {0}; modify((int*)&i, 1); // ok //modify((int*)&j, 2); // error modify((int*)&array[0], 3); // ok //modify((int*)&g_array[0], 4); // error printf("i = %d\n", i); printf("j = %d\n", j); printf("array[0] = %d\n", array[0]); printf("g_array[0] = %d\n", g_array[0]); return 0; }
下面為輸出結(jié)果:
如果把注釋去掉,就會(huì)報(bào)段錯(cuò)誤:
這就對(duì)應(yīng)上面說(shuō)的,如果修改 const 修飾的全局生命周期的變量,程序就會(huì)發(fā)生崩潰。
四、const 修飾函數(shù)參數(shù)和返回值
- const 修飾函數(shù)參數(shù)表示在函數(shù)體內(nèi)不希望改變參數(shù)的值
- const 修飾函數(shù)返回值表示返回值不可改變,多用于返回指針的情形
小貼士:C 語(yǔ)言中的字符串字面量存儲(chǔ)于只讀存儲(chǔ)區(qū)中,在程序中需要使用 const char* 指針。
下面看一段const 修飾函數(shù)參數(shù)與返回值的代碼吧:
#include <stdio.h> const char* f(const int i) { //i = 5; return "Autumn Ze"; } int main() { const char* pc = f(0); printf("%s\n", pc); //pc[6] = '_'; //printf("%s\n", pc); return 0; }
下面為輸出結(jié)果:
如果把下面的語(yǔ)句去掉注釋
//pc[6] = '_'; //printf("%s\n", pc);
運(yùn)行程序就會(huì)報(bào)錯(cuò),不能?chē)L試去修改只讀變量:
五、volatile 解析
- volatile 可理解為“編譯器警告指示字”
- volatile 告訴編譯器必須每次去內(nèi)存中取變量值
- volatile 主要修飾可能被多個(gè)線程訪問(wèn)的變量
- volatile 也可以修飾可能被未知因數(shù)更改的變量
如下:
六、小結(jié)
- const 使得變量具有只讀屬性
- const 不能定義真正意義上的常量
- const 將具有全局生命期的變量存儲(chǔ)于只讀存儲(chǔ)區(qū)
- volatile 強(qiáng)制編譯器減少優(yōu)化,必須每次從內(nèi)存中取值
到此這篇關(guān)于C語(yǔ)言詳細(xì)分析講解關(guān)鍵字const與volatile的用法的文章就介紹到這了,更多相關(guān)C語(yǔ)言 const與volatile內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
QT線程池的使用(QThreadPool類(lèi)和QRunnable類(lèi))
本文主要介紹了QT線程池的使用(QThreadPool類(lèi)和QRunnable類(lèi)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04C語(yǔ)言實(shí)現(xiàn)掃雷小游戲的示例代碼
這篇文中主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)經(jīng)典的掃雷小游戲。掃雷小游戲主要是利用字符數(shù)組、循環(huán)語(yǔ)句和函數(shù)實(shí)現(xiàn),感興趣的小伙伴可以了解一下2022-10-10C++ sdl實(shí)現(xiàn)渲染旋轉(zhuǎn)視頻的方法分享
一般情況下播放視頻時(shí)不需要旋轉(zhuǎn),但是如果是移動(dòng)端錄制的視頻有時(shí)會(huì)出現(xiàn)rotate參數(shù),且視頻寬高也是互換的。所以本文為大家準(zhǔn)備了利用sdl實(shí)現(xiàn)渲染旋轉(zhuǎn)視頻的方法,需要的可以參考一下2022-12-12C++學(xué)習(xí)之Lambda表達(dá)式的用法詳解
Lambda?表達(dá)式(lambda?expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來(lái)為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下2022-07-07C++實(shí)現(xiàn)數(shù)獨(dú)快速求解
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)數(shù)獨(dú)快速求解的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01C語(yǔ)言實(shí)現(xiàn)三子棋小游戲的示例代碼
這篇文章主要介紹了如何通過(guò)C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,三子棋小游戲的實(shí)現(xiàn)主要依賴(lài)于循環(huán)語(yǔ)句、函數(shù)和數(shù)組,感興趣的小伙伴可以嘗試一下2022-10-10C語(yǔ)言 詳細(xì)講解接續(xù)符和轉(zhuǎn)義符的使用
接續(xù)符是用來(lái)告訴編譯器行為的符號(hào),那編譯器遇到接續(xù)符是什么行為呢,就是去掉接續(xù)符,然后把下一行連接到現(xiàn)在這行上面,轉(zhuǎn)義符是主要用于表示無(wú)回顯字符,也用于表示常規(guī)字符,轉(zhuǎn)義符必須放在單引號(hào)或者雙引號(hào)里面2022-04-04