大家好,我是嵌入式老林,從事嵌入式軟件開發(fā)多年,今天分享的內(nèi)容是C語言面試最常問的三個(gè)關(guān)鍵字,希望能對(duì)你有所幫助。
C語言面試最常問的關(guān)鍵字
一,static關(guān)鍵字的作用
a) 修飾局部變量 ,會(huì)改變局部變量的生命周期,不改變作用域(在函數(shù)執(zhí)行完后,該靜態(tài)局部變量還在,不會(huì)被釋放,但不能在其它地方使用);靜態(tài)局部變量的初始化只會(huì)執(zhí)行一次
b) 修飾全局變量 ,表示該全局變量只能在本文件使用,不能跨文件使用
c) 修飾函數(shù) ,表示該函數(shù)只能在本文件中使用,不能跨文件使用
static修飾的變量存放在靜態(tài)存儲(chǔ)區(qū),會(huì)默認(rèn)初始化為0,而且修飾的全局變量和函數(shù)只能在本文件中使用,可防止重名。
二,const 關(guān)鍵字的作用
const 是 constant 的縮寫,意思是“恒定不變的”!用來定義只讀變量的,或者說 const 是定義常量的關(guān)鍵字
2.1, 修飾局部變量 ,被修飾變量的值不能改變。用const修飾變量時(shí),一定要給變量初始化,否則之后就不能再進(jìn)行賦值了。
const int i = 10; //正確
int const i = 10 // 正確,這兩種寫法是等價(jià)的
i = 20; //錯(cuò)誤,常量值不可被改變
const int j; //錯(cuò)誤,未被初始化
2.2, 修飾指針 ,可以指定指針本身為const,也可以指定指針?biāo)傅臄?shù)據(jù)為const
常量指針 ,本質(zhì)上是個(gè)指針,指針指向的內(nèi)容是常量,指針本身是可以變的,可指向其他地址
int a = 5;
int b = 10;
const int* n = &a;
int const* n = &a; //這兩種定義方式都是一樣的,表示常量指針
*n = 6; //錯(cuò)誤,不能改變 n所指向?qū)ο蟮闹?span>
a = 6; //正確,不能通過這個(gè)指針改變變量的值,但是還是可以通過其他的引用來改變變量的值的。
n = &b; //正確,常量指針指向的指不能改變,但指針可變,可指向其他地址
指針常量 ,本質(zhì)上是個(gè)常量,表示常量是個(gè)指針類型,不能再指向其他的地址,指向的內(nèi)容可變
int nValue1 = 10;
int nValue2 = 20;
int* const constPoint = &nValue1;
//constPoint = & nValue2; //錯(cuò)誤,不能改變constPoint本身的值
*constPoint = 40; //正確,可以改變constPoint所指向的對(duì)象,此時(shí)nValue1 = 40
指向常量的常指針
是以上兩種的結(jié)合,指針指向的位置不能改變并且也不能通過這個(gè)指針改變變量的值,但是依然可以通過其他的普通指針改變變量的值。
const int nConstValue1 = 5;
const int nConstValue2 = 15;
const int* const pPoint = &nConstValue1;
//*pPoint = 55; //錯(cuò)誤,不能改變pPoint所指向?qū)ο蟮闹?span>
//pPoint = &nConstValue2; //錯(cuò)誤,不能改變pPoint本身的值
const助記方法
把一個(gè)聲明從右向左讀。( * 讀成 pointer to )
char * const cp; // cp is a const pointer to char
const char * p; // p is a pointer to const char;
char const * p; // 同上
2.3, 修飾函數(shù)形參
根據(jù)常量指針與指針常量,const修飾函數(shù)的參數(shù)也是分為三種情況
- a)防止修改指針指向的內(nèi)容
void StringCopy(char* strDes, const char* strSrc);
其中 strSrc是輸入?yún)?shù),strDes是輸出參數(shù)。給 strSrc 加上 const 修飾后,如果函數(shù)體內(nèi)的語句試圖改動(dòng) strSrc 的內(nèi)容,編譯器將指出錯(cuò)誤。
- b) 防止修改指針指向的地址
void swap ( int* const p1 , int* const p2 )
指針p1和指針p2指向的地址都不能修改。
- c) 以上兩種的結(jié)合。
void swap ( int* const p1 , const int* const p2 )
2.4,修飾函數(shù)的返回值
如果給以“指針傳遞”方式的函數(shù)返回值加 const 修飾,那么函數(shù)返回值(即指針)的內(nèi)容不能被修改,該返回值只能被賦給加const 修飾的同類型指針。
舉個(gè)例子:
const char* GetString(void);
char* str = GetString(); // 錯(cuò)誤,會(huì)出現(xiàn)編譯錯(cuò)誤
const char* str = GetString(); // 正確,類型要一致
三,volatile關(guān)鍵字的作用
volatile 本意是“易變的”,指變量是隨時(shí)可能發(fā)生變化的。系統(tǒng)總是重新從它所在的內(nèi)存讀取數(shù)據(jù),即使它前面的指令剛剛從該處讀取過數(shù)據(jù)。即變量前加這個(gè)關(guān)鍵字,編譯器對(duì)訪問該變量的代碼就不再進(jìn)行優(yōu)化,從而可以提供對(duì)特殊地址的穩(wěn)定訪問
b) 一個(gè)中斷服務(wù)程序中修改的供其它程序檢測(cè)的變量
c) 多線程中各任務(wù)間共享的變量,可以關(guān)閉系統(tǒng)調(diào)度
這幾種情況經(jīng)常還要同時(shí)考慮數(shù)據(jù)的完整性(相互關(guān)聯(lián)的幾個(gè)標(biāo)志讀了一半被打斷了重寫),在a)中只能依靠硬件的良好設(shè)計(jì),b)中可以通過關(guān)中斷來實(shí)現(xiàn),c)中禁止任務(wù)調(diào)度。
編譯器的優(yōu)化:
在本次線程內(nèi), 當(dāng)讀取一個(gè)變量時(shí),為提高存取速度,編譯器優(yōu)化時(shí)有時(shí)會(huì)先把變量讀取到一個(gè)寄存器中;以后,再取變量值時(shí),就直接從寄存器中取值;當(dāng)變量值在本線程里改變時(shí),會(huì)同時(shí)把變量的新值copy到該寄存器中,以便保持一致。
當(dāng)變量在因別的線程等而改變了值,該寄存器的值不會(huì)相應(yīng)改變,從而造成應(yīng)用程序讀取的值和實(shí)際的變量值不一致。
當(dāng)該寄存器在因別的線程等而改變了值,原變量的值不會(huì)改變,從而造成應(yīng)用程序讀取的值和實(shí)際的變量值不一致。
其他問題
1)一個(gè)參數(shù)既可以是const還可以是volatile嗎?
可以的,例如只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖?。它是const因?yàn)槌绦虿粦?yīng)該試圖去修改它。
2)一個(gè)指針可以是volatile 嗎?
可以,當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。
評(píng)論