在 C 語言中,我們經(jīng)常會見到 const 和 volatile 這兩個關(guān)鍵字,那么我們今天就來介紹下這兩個關(guān)鍵字。
在嵐山等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站制作 網(wǎng)站設(shè)計制作按需策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都營銷網(wǎng)站建設(shè),外貿(mào)營銷網(wǎng)站建設(shè),嵐山網(wǎng)站建設(shè)費用合理。先來介紹 const 關(guān)鍵字。提起 const 關(guān)鍵字,我們可能首先想到的是經(jīng)過它修飾的變量便是常量了。其實我們這種想法是錯誤的,其實 const 修飾的變量是只讀的,其本質(zhì)還是變量。它修飾的局部變量是在棧上分配空間的,它修飾的全局變量在全局數(shù)據(jù)區(qū)分配空間(也就是我們平時所說的 read-only data 段),const 只在編譯期有用,在運行期無效。注意:const 修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現(xiàn)在賦值符號的左邊。
在現(xiàn)代的 C 語言編譯器中,修改 const 全局變量將導(dǎo)致程序崩潰。但是得注意標準 C 語言編譯器不會將 const 修飾的全局變量存儲于只讀存儲區(qū),而是存儲于可修改的全局數(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; }
我們來分析下這個示例代碼,cc 是 const 修飾的局部變量,是分配在棧上的。也就意味著它的屬性是只讀的,其本質(zhì)還是變量。因而我們可以通過第13行的指針操作來改變它的值,所以第11行和第15行打印出的值分被為 1 和 3;而 g_cc 不同,因為它是個 const 修飾的全局變量,因而會被放在只讀數(shù)據(jù)段。所以它的值不能被改變。以上的分析是基于現(xiàn)代的 C 語言編譯器,如果是以前的 C 語言編譯器(如 BCC)則不會這樣處理,會將全局變量存儲于可修改的全局數(shù)據(jù)區(qū),其值依然可以改變。我們分別用現(xiàn)代編譯器和 BCC 編譯器編譯,圖一為現(xiàn)代 C 語言編譯器gcc編譯的結(jié)果,圖二為 BCC 編譯的結(jié)果。
圖一
圖二
我們可以看到同一份代碼在兩個編譯器上竟然出現(xiàn)了兩個結(jié)果,在 gcc 中出現(xiàn)了段錯誤,而在 BCC 中則通過指針順利的改變了由 const 修飾的 g_cc 全局變量變量。由此證明了我們的分析是對的。
C語言中的 const 使得變量具有只讀屬性,現(xiàn)代 C 編譯器中的 const 將具有全局生命周期的變量存儲于只讀存儲區(qū),const 不能定義真正意義上的常量!?。?/p>
下面我們來分析這個示例代碼,代碼如下:
#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; }
在這份代碼中,我們發(fā)現(xiàn)變量 i 的定義竟然是 int const 的,其實這樣也就相當于 const int i;由于它是局部變量,分配在棧上。因而在被 const 修飾后,就具有只讀屬性,所以還是可以通過指針來改變的。但是變量 j 就不一樣啦,它是由 static 修飾的,其具有全局的生命周期,所以是不能通過指針來改變的,因而第17行代碼將會報錯。第18行我們可以通過指針來改變 array 數(shù)組第一個元素,而 g_array 數(shù)組是全局的,所以就不能通過指針來改變它的值,而已第19行會報錯。同樣的上面的分析我們是基于現(xiàn)代的編譯器,在 BCC 中不適用。下來我們就來編譯下,看看是否如我們所分析的那樣。
我們用 gcc 編譯直接報段錯誤,那么我們來把第17和19行注釋掉,再次編譯。
下來我們再用 BCC 來編譯下,結(jié)果如下
那么我們發(fā)現(xiàn)代碼直接通過,而且值也都改變了。由此可以看出現(xiàn)代的編譯器越來越強大了,已經(jīng)將 const 的意思表達的更加完善了。下面這張圖更好的闡釋了 const 的意思
那么 const 修飾函數(shù)參數(shù)又是什么意思呢?它表示在函數(shù)體內(nèi)不希望改變參數(shù)的值,const 修飾函數(shù)返回值表示返回值不可改變,多用于返回指針的情形。C 語言中的字符串字面量存儲于只讀存儲區(qū),在程序中需要使用 const char* 指針。下來我們來分析個示例,代碼如下:
#include <stdio.h> const char* f(const int i) { i = 5; return "hello world"; } int main() { const char* pc = f(0); printf("%s\n", pc); pc[6] = '_'; printf("%s\n", pc); return 0; }
我們可以看出變量 i 是由 const 修飾的,因而第5行的代碼肯定會報錯。在第16行我們想要將中間的那個空格改變成“_”,但是返回的字符字面量是 const 型的,因而不能改變,在這塊也會報錯。我們編譯下看看結(jié)果是否如此
我們可以看出這兩行代碼已經(jīng)報錯。我們注釋掉這兩行代碼,再次編譯,結(jié)果如下
我們接下來再來分析下 volatile 關(guān)鍵字。它可理解為“編譯器警告指示字”,告訴編譯器必須每次去內(nèi)存中取變量值,主要修飾可能被多個線程訪問的變量同時也可以修飾可能被未知因數(shù)更改的變量。我們在嵌入式的開發(fā)中,常常會用的多線程。那么在這個線程里一個變量的值被改變,我們在另一個線程里需要用到它原來的值,但是已經(jīng)被改變了,這時怎么辦呢?只能去內(nèi)存中讀取這個變量的值,這時用 volatile 修飾就OK了。在每次需要用到這個變量時,便會去內(nèi)存中讀取,雖然比較耗時一點,但是是安全的!
那么我們今天學(xué)習(xí)了 const 和 volatile 的相關(guān)知識,總結(jié)如下:1、const 使得變量具有只讀屬性;2、它不能定義真正意義上的常量;3、const 將具有全局生命期的變量存儲于只讀存儲區(qū);4、volatile 強制編譯器減少優(yōu)化,必須每次從內(nèi)存中取值。后面我們會繼續(xù)對 C 語言的學(xué)習(xí)。
歡迎大家一起來學(xué)習(xí) C 語言,可以加我QQ:243343083。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)站欄目:C之const和volatile(九)-創(chuàng)新互聯(lián)
網(wǎng)站鏈接:http://jinyejixie.com/article46/dhdgeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、網(wǎng)站維護、品牌網(wǎng)站制作、網(wǎng)站內(nèi)鏈、虛擬主機、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容