關(guān)于const的用法,現(xiàn)在大概前前后后應(yīng)該寫了有兩篇文章,以前學(xué)習(xí)的時候,用法體會不是那么深刻,為啥這么說呢,因為在學(xué)習(xí)c++的時候,會發(fā)現(xiàn)const關(guān)鍵字有新的玩法,關(guān)于這個新的玩法,大家可以去看最近學(xué)習(xí)總結(jié)寫的c++文章專輯。
一、const的用法:
1、const只讀變量:
const修飾的變量是只讀的,本質(zhì)上還是變量
const修飾的局部變量在棧上分配空間
const修飾的全局變量在全局?jǐn)?shù)據(jù)區(qū)分配空間
const只在編譯期有用,在運行期沒有用
注:const修飾的變量不是真的常量,它只是告訴編譯器該變量不能出現(xiàn)在賦值符號的左邊
2、const全局變量的分歧:
在現(xiàn)代c語言編譯器中,修改const全局變量將導(dǎo)致程序崩潰
標(biāo)準(zhǔn)c語言編譯器不會將const修飾的全局變量存儲于只讀存儲區(qū)中,而是存儲于可修改的全局?jǐn)?shù)據(jù)區(qū),其值依然可以改變
3、代碼示例:
(1)只讀變量代碼示例:
#include <stdio.h>
int main()
{
const int a =10;
printf("a = %d",a);
a=20;
printf("a = %d",a);
return 0;
}
運行結(jié)果:
test.c: In function ‘main’:
test.c:8:4: error: assignment of read-only variable ‘a(chǎn)’
a=20;
^
注解:顯示這個結(jié)果很正常,變量a被const修飾了,它就成了只讀的。
(2)如果對變量a的值進行修改:
#include <stdio.h>
int main()
{
const int a =10;
int *p =(int *) &a;
printf("a = %d",a);
*p=20;
printf("a = %d",a);
return 0;
}
運行結(jié)果:
root@txp-virtual-machine:/home/txp# ./a.out
a = 10
a = 20
注解:通過指針的方式,就能夠把a的值進行修改,這也論證了“const修飾的變量是只讀的,本質(zhì)上還是變量”這句話
(3)const修飾全局變量:
代碼版本一
#include <stdio.h>
const int b = 40;
int main()
{
printf("b = %d",b);
b=20;
printf("b = %d",b);
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# gcc test.c
test.c: In function ‘main’:
test.c:10:4: error: assignment of read-only variable ‘b’
b=20;
^
注解:跟const修飾棧上的變量用法一樣
代碼版本二
#include <stdio.h>
const int b = 40;
int main()
{
int *p =(int *) &b;
printf("b = %d",b);
*p=20;
printf("b = %d",b);
return 0;
}
運行結(jié)果:
root@txp-virtual-machine:/home/txp# ./a.out
b = 40
Segmentation fault (core dumped)
注解:這里出現(xiàn)了段錯誤,這也驗證了我們上面所說的“修改const全局變量將導(dǎo)致程序崩潰”。
同時為了驗證“標(biāo)準(zhǔn)c語言編譯器不會將const修飾的全局變量存儲于只讀存儲區(qū)中,而是存儲于可修改的全局?jǐn)?shù)據(jù)區(qū),其值依然可以改變”這句話,我把這段代碼放到dev c++上進行試驗:
說明:我這個版本的編譯器支持標(biāo)準(zhǔn)c語言,所以沒導(dǎo)致程序崩潰,能夠正常運行
4、const的本質(zhì)
c語言中的const使得變量具有只讀屬性
現(xiàn)代c編譯器中的const將具有全局生命周期的變量存儲于只讀存儲區(qū),不是放在全局?jǐn)?shù)據(jù)區(qū)
注:const不能定義真正意義上的常量;同時這里注意static關(guān)鍵字修飾的變量,它的生命周期和全局變量一樣。
代碼示例:
#include <stdio.h>
const int Array[5] = {0};
void fun(int *p,int v)
{
*p=v;
}
int main()
{
int const i =1;
const static int j =2;
int const array[5] = {0};
fun((int *)&i,1);
fun((int *)&j,2);
fun((int *)&array[2],3);
fun((int *)&Array[1],4);
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# ./a.out
Segmentation fault (core dumped)
注解:這里會有段錯誤,錯誤出現(xiàn)在const+static修飾的j變量對其進行修改,還有const修飾的全局?jǐn)?shù)組。
5、const修飾函數(shù)參數(shù)和返回值
const修飾函數(shù)參數(shù)表示在函數(shù)體內(nèi)不希望改變參數(shù)的值
const修飾函數(shù)返回值表示返回值不可改變,多用于返回指針的情形
在c語言中的字符串字面量存儲于只讀存儲區(qū)中,在程序中需要使用const char* 指針,例如:
const char * s = "TXP嵌入式";//字符串字面量
代碼示例:
#include <stdio.h>
const char*fun(const int i)
{
i=8;
return "TXP";
}
int main()
{
const char * p=fun(0);
printf("%s",p);
p[1]='_';
printf("%s",p);
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# gcc test.c
test.c: In function ‘fun’:
test.c:5:4: error: assignment of read-only parameter ‘i’
i=8;
^
test.c: In function ‘main’:
test.c:12:5: error: assignment of read-only location ‘*(p + 1u)’
p[1]='_';
^
注解:上面這樣寫,肯定有問題。
代碼進化:
#include <stdio.h>
const char*fun(const int i)
{
// i=8;
return "TXP";
}
int main()
{
const char * p=fun(0);
printf("%s",p);
// p[1]='_';
// printf("%s",p);
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# ./a.out
TXP
二、volatile的用法
老實說,這個關(guān)鍵字在面試題目里面經(jīng)常會出現(xiàn),但是平時學(xué)習(xí)的時候,如果你沒有真正理解這其中的含義,在筆試的時候,腦袋里面可能依稀是記得有那么幾個結(jié)論,但是有時候吧,一緊張就把結(jié)論給忘了,也不是不可能,所以說,咋們還是老實一點,得真正把它原理搞明白才行,這樣上來戰(zhàn)場就不怕了,以后寫代碼也就少一點bug。
1、volatile的常用結(jié)論(volatile英文本意就是易變的意思)
這里我先給結(jié)論,然后再給一個例子,把這個例子的講明白,所有結(jié)論就都明白了。
volatile可理解為“編譯器警告指示字”
volatile告訴編譯器必須每次去內(nèi)存中取變量值
volatile主要修飾可能被多個線程訪問的變量
volatile也可以修飾可能被未知因素更改的變量
volatile可以修飾一個中斷子程序中會訪問到的非自動變量
2、分析原理
大家可能平時在博客學(xué)習(xí),都會發(fā)現(xiàn)講解編譯器優(yōu)化的,然后加了volatile關(guān)鍵來修飾變量,就告訴編譯器不要去優(yōu)化這個變量了,那么這里的優(yōu)化到底是什么意思呢?
從字面上來理解優(yōu)化兩個字,意思就是最優(yōu)值(變量的值不會改變),這里我用一個簡單代碼來說明一下:
#include <stdio.h>
int main()
{
int a =1;//volatile int a =0;
while(a)
{
}
}
說明:上面的代碼,如果變量a沒有加volatile修飾的話,編譯器就會優(yōu)化它(也就是a的值一直不變),所以while就一直死循環(huán);然后我如果加了volatile來修飾的話,編譯器就不會去優(yōu)化變量a,不優(yōu)化的意思就是說,變量a的值可能就會改變,while就不會一直死循環(huán)。
當(dāng)然這里為了好理解,我說的不是很專業(yè),沒有從寄存器和內(nèi)存的角度去說。(我也不想那么去講解,簡單理解了就行)
總之一句話:上面的結(jié)論中,volatile修飾的都是變量,變量就可能改變,不會被編譯器優(yōu)化;只是說我們上面的結(jié)論應(yīng)用場景不同而已。
三、總結(jié)
const使得變量具有只讀屬性
const不能定義真正意義上的常量
const將具有全局生命周期的變量存儲于只讀存儲區(qū)
volatile強制編譯器減少優(yōu)化,必須每次從內(nèi)存中取值
好了,今天的分享就到這里,如果文章中有錯誤或者不理解的地方,可以交流互動,一起進步。我是txp,下期見!
-
C語言
+關(guān)注
關(guān)注
183文章
7644瀏覽量
145565 -
volatile
+關(guān)注
關(guān)注
0文章
46瀏覽量
13729 -
CONST
+關(guān)注
關(guān)注
0文章
45瀏覽量
8761
發(fā)布評論請先 登錄
volatile的修飾符
C語言嵌入式系統(tǒng)編程注意事項-內(nèi)存操作
請問如何實現(xiàn)C語言訪問MCU寄存器?
什么是??volatile
C語言特性
一文了解Mojo編程語言
自動駕駛中Transformer大模型會取代深度學(xué)習(xí)嗎?
深入理解C語言:C語言循環(huán)控制
C語言中結(jié)構(gòu)體與聯(lián)合體的深度解析:內(nèi)存布局與應(yīng)用場景
單片機編程關(guān)鍵字之volatile
帶你在單片機編程中熟練使用const(可下載)
如何在 樹莓派 上編寫和運行 C 語言程序?
為什么學(xué)了C語言,卻寫不出像樣的項目?
C語言之const和volatile的深度學(xué)習(xí)
評論