溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言的const和volatile怎么使用

發(fā)布時間:2021-11-22 15:22:35 來源:億速云 閱讀:169 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“C語言的const和volatile怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“C語言的const和volatile怎么使用”吧!

一、const的用法:

1、const只讀變量:

  • const修飾的變量是只讀的,本質(zhì)上還是變量

  • const修飾的局部變量在棧上分配空間

  • const修飾的全局變量在全局?jǐn)?shù)據(jù)區(qū)分配空間

  • const只在編譯期有用,在運(yùn)行期沒有用

注: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\n",a);

   a=20;
   printf("a = %d\n",a);
  
  return 0;
}
 

運(yùn)行結(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的值進(jìn)行修改:

#include <stdio.h>

int main()
{
   const int a =10;
   int *p =(int *) &a;
   printf("a = %d\n",a);

   *p=20;
   printf("a = %d\n",a);


  return 0;
}

 

運(yùn)行結(jié)果:

root@txp-virtual-machine:/home/txp# ./a.out
a = 10
a = 20

 

注解:通過指針的方式,就能夠把a(bǔ)的值進(jìn)行修改,這也論證了“const修飾的變量是只讀的,本質(zhì)上還是變量”這句話

(3)const修飾全局變量:

代碼版本一

#include <stdio.h>
const int b = 40;

int main()
{
   
 
   printf("b = %d\n",b);
   b=20;
   printf("b = %d\n",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\n",b);

   *p=20;
   printf("b = %d\n",b);


  return 0;
}
 

運(yùn)行結(jié)果:

root@txp-virtual-machine:/home/txp# ./a.out
b = 40
Segmentation fault (core dumped)
 

注解:這里出現(xiàn)了段錯誤,這也驗(yàn)證了我們上面所說的“修改const全局變量將導(dǎo)致程序崩潰”。

同時為了驗(yàn)證“標(biāo)準(zhǔn)c語言編譯器不會將const修飾的全局變量存儲于只讀存儲區(qū)中,而是存儲于可修改的全局?jǐn)?shù)據(jù)區(qū),其值依然可以改變”這句話,我把這段代碼放到dev c++上進(jìn)行試驗(yàn):

C語言的const和volatile怎么使用  

說明:我這個版本的編譯器支持標(biāo)準(zhǔn)c語言,所以沒導(dǎo)致程序崩潰,能夠正常運(yùn)行

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變量對其進(jìn)行修改,還有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\n",p);
    p[1]='_';
    printf("%s\n",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]='_';
     ^
 

注解:上面這樣寫,肯定有問題。

代碼進(jìn)化:

#include <stdio.h>

const char*fun(const int i)
{
//   i=8;
    return "TXP";
}
int main()
{
   const char * p=fun(0);
    printf("%s\n",p);
  //  p[1]='_';
   // printf("%s\n",p);

    return 0;


}
 

輸出結(jié)果:

root@txp-virtual-machine:/home/txp# ./a.out
TXP
 

二、volatile的用法

老實(shí)說,這個關(guān)鍵字在面試題目里面經(jīng)常會出現(xiàn),但是平時學(xué)習(xí)的時候,如果你沒有真正理解這其中的含義,在筆試的時候,腦袋里面可能依稀是記得有那么幾個結(jié)論,但是有時候吧,一緊張就把結(jié)論給忘了,也不是不可能,所以說,咋們還是老實(shí)一點(diǎn),得真正把它原理搞明白才行,這樣上來戰(zhàn)場就不怕了,以后寫代碼也就少一點(diǎ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)存的角度去說。(我也不想那么去講解,簡單理解了就行)

到此,相信大家對“C語言的const和volatile怎么使用”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI