久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式招聘 > 嵌入式面試題 > 嵌入式最基本的(de)面試題,老鳥(niao)總結(jie)

嵌入式(shi)最基本的面試題(ti),老鳥總(zong)結 時(shi)間:2018-08-22      來源:未知(zhi)

下面總結出了一下嵌入式面試(shi)(shi)中最常見的(de)一些(xie)題型,而且都(dou)是(shi)每(mei)次面試(shi)(shi)都(dou)會(hui)提及到的(de),因為我面試(shi)(shi)了很多公司總結的(de)一些(xie)經驗,可以收(shou)藏學習哦。

常見基本(ben)類型的(de)字節(jie)大小(xiao)

32位操作系統

char :1個字節(jie)(固定)

*(即(ji)指針變量): 4個字(zi)節(32位(wei)機的尋址空(kong)間是4個字(zi)節。同理64位(wei)編譯(yi)器(qi))(變化*)

short int : 2個字節(固定)

int: 4個字(zi)節(固(gu)定)

unsigned int : 4個字節(固定)

float: 4個(ge)字節(固(gu)定)

double: 8個(ge)字(zi)節(固定)

long: 4個字節

unsigned long: 4個字節(變(bian)化*,其(qi)實就是尋(xun)址(zhi)控件的地(di)址(zhi)長度數值(zhi))

long long: 8個字節(jie)(固(gu)定)

1.指向字符串常(chang)量(liang)的指針,指向字符串的常(chang)量(liang)指針(const)

const char* p = "hello"; // 指向(xiang) "字(zi)符(fu)串(chuan)常(chang)量"

p[0] = 'X'; // 錯誤(wu)! 想要修(xiu)改字(zi)符串的第(di)一(yi)個字(zi)符. 但是(shi)常量(liang)不允許(xu)修(xiu)改

p = p2; // 正(zheng)確! 讓p指(zhi)向另外一個指(zhi)針(zhen).

char* const p = "hello"; // 指(zhi)(zhi)向字符串的" 常量的指(zhi)(zhi)針(zhen)"

p[0] = 'X'; // 正確! 允許修改字(zi)符串(chuan), 因為該字(zi)符串(chuan)不是常量(liang)

p = p2; // 錯誤! 指針是(shi)常量, 不許修改p的指向

char const * 和 const char* 是(shi)一樣的. const 的位置(zhi)在char左邊還是(shi)右邊都一樣.

常量(liang)指針(zhen)的(de)const應當(dang)寫在 *星(xing)號的(de)右邊.

指向常(chang)量字符串(chuan)的常(chang)量指針的寫法(fa)是 const char* const p = "xx"; 要2個const

2.typedef & #define的問題

有(you)下面兩種定(ding)義(yi)pStr數(shu)據類型的方法,兩者(zhe)有(you)什么不(bu)同?哪一(yi)種更好一(yi)點?

typedef char* pStr;

#define pStr char*;

分(fen)析(xi):通常(chang)講(jiang),typedef要比#define要好(hao),特別是在(zai)有指(zhi)針的場合(he)。請看(kan)例子(zi):

typedef char* pStr1;

#define pStr2 char *

pStr1 s1, s2;

pStr2 s3, s4;

在上述的變(bian)量定(ding)(ding)義中,s1、s2、s3都(dou)被(bei)定(ding)(ding)義為char *,而s4則定(ding)(ding)義成(cheng)了char,不是(shi)我們所預(yu)期(qi)的指針變(bian)量,根(gen)本原(yuan)因就在于#define只是(shi)簡單的字(zi)(zi)符串替(ti)換而typedef則是(shi)為一個類型起新名字(zi)(zi)。上例中define語句(ju)必須寫成(cheng) pStr2 s3, *s4; 這(zhe)這(zhe)樣才能(neng)正常執行。

3.const的(de)問題

(1)可以定義(yi)const常量(liang),具有不可變性。

例如:const int Max=100; int Array[Max];

(2)便于進行類型檢(jian)查,使編(bian)譯器對處理(li)內容有(you)更(geng)多了(le)解(jie),消除了(le)一些(xie)隱(yin)患。

例如(ru): void f(const int i) { .........} 編譯器就會知道(dao)i是一個常量,不允許修改(gai);

(3)可(ke)以(yi)(yi)避免意(yi)義模糊的(de)數字出現,同樣可(ke)以(yi)(yi)很(hen)方便地進行參數的(de)調整和修(xiu)改。

如(1)中,如果(guo)想修改Max的內(nei)容(rong),只需(xu)要:const int Max=you want;即可(ke)!

(4)可以保護被修(xiu)飾的東西,防止(zhi)意(yi)外的修(xiu)改,增強程(cheng)序的健(jian)壯性(xing)。 還是上面的例子,如(ru)果在函(han)數體內(nei)修(xiu)改了(le)i,編譯器就會報錯;

例如: void f(const int i) { i=10;//error! }

(5)可(ke)以節省空間,避免不必要的內(nei)存分配(pei)。 例如:

#define PI 3.14159 //常量(liang)宏

const doublePi=3.14159; //此時并未將(jiang)Pi放入RAM中 ......

doublei=Pi; //此(ci)時(shi)為Pi分配內存(cun),以后不再分配!

double I=PI; //編譯期間(jian)進行宏替換,分配內存(cun)

double j=Pi; //沒有內(nei)存分配

double J=PI; //再進行宏替(ti)換(huan),又一次分配內存(cun)!

const定(ding)義(yi)常(chang)量(liang)(liang)從匯編的角度來看,只是(shi)給(gei)(gei)出(chu)(chu)了(le)對應的內存地址,而不是(shi)象#define一樣給(gei)(gei)出(chu)(chu)的是(shi)立即數,所以,const定(ding)義(yi)的常(chang)量(liang)(liang)在程序運(yun)行(xing)過程中只有一份(fen)拷(kao)貝,而#define定(ding)義(yi)的常(chang)量(liang)(liang)在內存中有若干個拷(kao)貝。

(6)提高了效率。

編譯器通(tong)常不(bu)為(wei)普(pu)通(tong)const常量分配存儲空間,而是將它們(men)保存在符號表中(zhong),這使得它成(cheng)為(wei)一個編譯期間的常量,沒(mei)有(you)了存儲與讀(du)內存的操作,使得它的效率也很高。

sizeof與strlen的區別(bie):

char str[20]="0123456789";

int a=strlen(str); // a=10;strlen 計算字符串(chuan)的長度,以(yi)\0'為字符串(chuan)結束(shu)標記。

int b=sizeof(str); // b=20;sizeof 計算的(de)(de)(de)則(ze)是分配的(de)(de)(de)數組str[20] 所占的(de)(de)(de)內存空間的(de)(de)(de)大小(xiao),不受里面存儲的(de)(de)(de)內容影(ying)響.

上面是對靜態(tai)數組處(chu)理的(de)結(jie)果(guo),如(ru)果(guo)是對指(zhi)針(zhen),結(jie)果(guo)就不一樣了

char* ss = "0123456789";

sizeof(ss)結果(guo)4===》ss是指(zhi)向字(zi)(zi)符串(chuan)(chuan)常(chang)量(liang)的(de)(de)(de)(de)字(zi)(zi)符指(zhi)針,sizeof 獲(huo)(huo)得的(de)(de)(de)(de)是一個指(zhi)針的(de)(de)(de)(de)之(zhi)所(suo)占(zhan)的(de)(de)(de)(de)空間,應該(gai)是長整型的(de)(de)(de)(de),所(suo)以是4,sizeof(*ss) 結果(guo)1===》*ss是第(di)一個字(zi)(zi)符 其實就是獲(huo)(huo)得了(le)字(zi)(zi)符串(chuan)(chuan)的(de)(de)(de)(de)第(di)一位'0' 所(suo)占(zhan)的(de)(de)(de)(de)內(nei)存空間,是char類型的(de)(de)(de)(de),占(zhan)了(le)1位strlen(ss)= 10如果(guo)要(yao)獲(huo)(huo)得這個字(zi)(zi)符串(chuan)(chuan)的(de)(de)(de)(de)長度,則一定(ding)要(yao)使用 strlen

Sizeof結構(gou)體為(wei)結構(gou)體中定義的數據類型的總的空間(注(zhu)意(yi)字節對齊)。

Sizeof對union為(wei)union中(zhong)定義的(de)數據類型的(de)最大數據類型的(de)大小。

5 .auto, register, static分析

auto即C語(yu)言(yan)中(zhong)(zhong)局部變(bian)(bian)量(liang)(liang)的默(mo)認屬(shu)性,編譯器默(mo)認所有(you)的局部變(bian)(bian)量(liang)(liang)都(dou)是(shi)auto的,定義(yi)的變(bian)(bian)量(liang)(liang)都(dou)是(shi)在(zai)棧中(zhong)(zhong)分配內存(cun)。

static關鍵字指明變量的(de)(de)(de)“靜態(tai)”屬性,同時具(ju)有(you)“作用域限定符(fu)(fu)”的(de)(de)(de)意義(yi),修飾的(de)(de)(de)局部(bu)變量存(cun)儲在程序靜態(tai)區,static的(de)(de)(de)另一個意義(yi)是文(wen)件(jian)作用域標示(shi)符(fu)(fu)。

static修飾的全局(ju)變(bian)量作用域(yu)只是聲(sheng)明的文件中,static修飾的函(han)數作用域(yu)只是聲(sheng)明的文件中

register關鍵字指(zhi)明將變(bian)量(liang)存(cun)儲于寄存(cun)器中,register只(zhi)是(shi)請求(qiu)寄存(cun)器變(bian)量(liang),但不(bu)一定請求(qiu)成功。register變(bian)量(liang)的(de)必(bi)須是(shi)CPU寄存(cun)器可(ke)以接受的(de)值,不(bu)能用(yong)&運算符獲取register變(bian)量(liang)的(de)地址,這樣使用(yong)的(de)好處是(shi)處理快。

6. const, volatile同時修飾變量

(1) “編譯器(qi)一般不為(wei)const變量分配(pei)內(nei)存(cun)(cun),而(er)是將它(ta)保存(cun)(cun)在符號表(biao)中,這使得(de)它(ta)成為(wei)一個(ge)編譯期間(jian)的值(zhi),沒有了存(cun)(cun)儲與(yu)讀內(nei)存(cun)(cun)的操(cao)作。”

(2) volatile的作用是(shi)“告(gao)訴編譯(yi)器(qi),i是(shi)隨時(shi)可(ke)能發生變化的,每次使用它的時(shi)候必須從內存中取出i的值”。

一,const, volatile含義

(1)const含義是“請做為常量使用”,而(er)并非“放心(xin)吧,那肯定是個常量”。

 (2)volatile的含義是(shi)“請(qing)不要做自(zi)以為(wei)是(shi)的優化,這個值(zhi)可能變(bian)掉的”,而(er)并非“你(ni)可以修改這個值(zhi)”。

二,const, volatile的作用(yong)以(yi)及起作用(yong)的階段

(1)const只在(zai)編譯(yi)期(qi)有用,在(zai)運行(xing)期(qi)無(wu)用

const在(zai)編譯期(qi)保(bao)證(zheng)在(zai)C的(de)(de)“源代碼”里面,沒有(you)對其修(xiu)飾的(de)(de)變(bian)量(liang)進行修(xiu)改(gai)的(de)(de)地方(如(ru)有(you)則報錯,編譯不(bu)通過),而運行期(qi)該變(bian)量(liang)的(de)(de)值是否被改(gai)變(bian)則不(bu)受const的(de)(de)限制。

(2)volatile在(zai)編譯期(qi)和運(yun)行(xing)期(qi)都(dou)有用

在編(bian)譯期告訴編(bian)譯器:請不(bu)要(yao)做自以為是的優化,這個(ge)變量的值可能(neng)會變掉;

在運行期:每次用到該(gai)變量的(de)值,都從內(nei)存(cun)中取該(gai)變量的(de)值。

補充:編譯期 -- C編譯器(qi)將源代碼(ma)轉化為匯(hui)編,再轉化為機器(qi)碼(ma)的過程(cheng);運行期 -- 機器(qi)碼(ma)在(zai)CPU中執行的過程(cheng)。

三,const, volatile同(tong)時修飾一個變量

(1)合(he)法(fa)性

“volatile”的含(han)義并非是“non-const”,volatile和cons不(bu)構成反義詞,所以可以放一起修飾一個變量(liang)。

(2)同(tong)時(shi)修飾一個變量的含義(yi)

表(biao)示一個變量(liang)在程序(xu)(xu)編譯(yi)期(qi)不(bu)(bu)能被修改且不(bu)(bu)能被優化;在程序(xu)(xu)運(yun)行期(qi),變量(liang)值可修改,但每次(ci)用到該變量(liang)的(de)值都(dou)要從內存中(zhong)讀取(qu),以防止意外錯(cuo)誤。

7 、棧、堆、靜態存儲區

棧:主要函(han)數調(diao)用的使用

棧是從高地(di)(di)址(zhi)向低地(di)(di)址(zhi)方(fang)向使用,堆(dui)的方(fang)向相(xiang)反。

在(zai)一次函(han)數(shu)調(diao)用中(zhong),棧(zhan)中(zhong)將(jiang)被依次壓入:參數(shu),返(fan)回地址,EBP。如果函(han)數(shu)有局(ju)部變量,接下來,就(jiu)在(zai)棧(zhan)中(zhong)開辟相應的空(kong)間以構造變量。

在C語言(yan)程序中,參數的(de)(de)(de)壓棧(zhan)順序是反向的(de)(de)(de)。比如func(a,b,c)。在參數入(ru)棧(zhan)的(de)(de)(de)時候,是:先(xian)壓c,再壓b,最后a。在取(qu)參數的(de)(de)(de)時候,由于棧(zhan)的(de)(de)(de)先(xian)入(ru)后出,先(xian)取(qu)棧(zhan)頂(ding)的(de)(de)(de)a,再取(qu)b,最后取(qu)c。

堆:主要內存動態分(fen)配

空閑鏈表法,位圖法,對象池(chi)法等等 。

Int* p=(int*)malloc(sizeof(int));

靜態(tai)存儲區:保存全(quan)局變量和靜態(tai)變量

程(cheng)(cheng)序(xu)靜(jing)態(tai)存(cun)(cun)(cun)儲區隨著(zhu)程(cheng)(cheng)序(xu)的(de)(de)運(yun)行而(er)分配空(kong)間,直到程(cheng)(cheng)序(xu)運(yun)行結束,在程(cheng)(cheng)序(xu)的(de)(de)編譯期靜(jing)態(tai)存(cun)(cun)(cun)儲區的(de)(de)大小就(jiu)已經(jing)確定,程(cheng)(cheng)序(xu)的(de)(de)靜(jing)態(tai)存(cun)(cun)(cun)儲區主要用于保存(cun)(cun)(cun)程(cheng)(cheng)序(xu)中(zhong)的(de)(de)全局變量(liang)和靜(jing)態(tai)變量(liang)與棧和堆不同,靜(jing)態(tai)存(cun)(cun)(cun)儲區的(de)(de)信息最終(zhong)會(hui)保存(cun)(cun)(cun)到可執行程(cheng)(cheng)序(xu)中(zhong) 。

知識點(dian):堆棧段(duan)在(zai)程(cheng)序(xu)運行后才正式存在(zai),是(shi)程(cheng)序(xu)運行的基礎

 1.函數放(fang)在代碼段(duan):.Test section。 .text段(duan)存(cun)放(fang)的是程(cheng)序中的可(ke)執(zhi)行代碼

2.帶初(chu)始值的全局(ju)變量和(he)靜(jing)態變量在數據段:.data section。 .data段保存的是那些(xie)已經(jing)初(chu)始化了的全局(ju)變量和(he)靜(jing)態變量

3.不帶初始值得全(quan)局變量(liang)和靜態(tai)(tai)變量(liang)在.bss。 .bss段存(cun)放的(de)是(shi)未初始化(hua)的(de)全(quan)局變量(liang)和靜態(tai)(tai)變量(liang)

.rodata(read only)段(duan)存放程序中的常量值,如字符串常量

同是全局變(bian)量和(he)靜態變(bian)量,為什么初(chu)始(shi)化和(he)未初(chu)始(shi)化的(de)變(bian)量保(bao)存在不同的(de)段中?

答:為了啟動代(dai)(dai)碼的(de)簡單(dan)化,編(bian)譯鏈接(jie)器(qi)會把(ba)已初(chu)(chu)始化的(de)變(bian)量放在同一個(ge)段:.data,這(zhe)個(ge)段的(de)映像(包含了各個(ge)變(bian)量的(de)初(chu)(chu)值)保存在“只讀數據段”,這(zhe)樣啟動代(dai)(dai)碼就可以簡單(dan)地復(fu)制這(zhe)個(ge)映像到 .data 段,所有的(de)已初(chu)(chu)始化變(bian)量就都初(chu)(chu)始化了。而(er)未(wei)初(chu)(chu)始化變(bian)量也放在同一個(ge)段:.bss,啟動代(dai)(dai)碼簡單(dan)地調(diao)用 memset 就可以把(ba)所有未(wei)初(chu)(chu)始化變(bian)量都清0。

void *memset(void *s, int ch, size_t n);

函數解釋:將s中當前位置后面(mian)的(de)n個字節 (typedef unsigned int size_t )用(yong) ch 替換并返回 s 。

memset:作用是在一段內存塊中填充某個給(gei)定(ding)的值,它是對較大(da)的結構體或數組進行(xing)清零操作的一種最快方法

#define Malloc(type,n) (type*)malloc(n*sizeof(type))

8 、野指針

產生原因:

1、局(ju)部(bu)指針變量沒有初始(shi)化

2、使用已經釋(shi)放(fang)的(de)指(zhi)針

3、指(zhi)針所指(zhi)向的變量在指(zhi)針之前被銷(xiao)毀

A.用(yong)(yong)malloc申請了(le)內存(cun)之后,應該立(li)即檢查指(zhi)針(zhen)值是(shi)否為(wei)NULL,防止(zhi)使用(yong)(yong)為(wei)NULL的指(zhi)針(zhen):

B.牢記(ji)數(shu)組的(de)長度,防止(zhi)數(shu)組越界操作,考慮使用柔性數(shu)組

C.動態(tai)申請(qing)操作(zuo)必須和(he)釋(shi)放操作(zuo)匹(pi)配(pei),防止內存(cun)泄露和(he)多次釋(shi)放

D.free指針之后必(bi)須立即賦值為NULL

9 、void類型指針

指(zhi)(zhi)(zhi)針(zhen)(zhen)有兩(liang)個屬性:指(zhi)(zhi)(zhi)向變量/對象的地(di)址(zhi)和長度(du),但是(shi)指(zhi)(zhi)(zhi)針(zhen)(zhen)只存儲地(di)址(zhi),長度(du)則取決于指(zhi)(zhi)(zhi)針(zhen)(zhen)的類(lei)(lei)型;編譯器(qi)根據指(zhi)(zhi)(zhi)針(zhen)(zhen)的類(lei)(lei)型從指(zhi)(zhi)(zhi)針(zhen)(zhen)指(zhi)(zhi)(zhi)向的地(di)址(zhi)向后尋址(zhi),指(zhi)(zhi)(zhi)針(zhen)(zhen)類(lei)(lei)型不同則尋址(zhi)范(fan)圍也不同,比如:

int*從指定地(di)址向后尋找4字節作為(wei)變量的存儲單元

 double*從(cong)指定地址(zhi)向后(hou)尋找(zhao)8字(zi)節(jie)作為變量(liang)的存儲單元(yuan)

void即“無類型”,void *則為“無類型指(zhi)針”,可以指(zhi)向任何數據類型。

void指(zhi)針可以指(zhi)向(xiang)任意類型(xing)的數據(ju)(ju),即可用任意數據(ju)(ju)類型(xing)的指(zhi)針對void指(zhi)針賦值。例如

int *pint;

void *pvoid; //它沒有(you)類型,或者說這個類型不能判斷出指(zhi)向對象的長度

pvoid = pint; //只獲(huo)(huo)得變量/對象(xiang)地址而不(bu)獲(huo)(huo)得大小,但是不(bu)能 pint =pvoid;

9.2 如(ru)果要將(jiang)pvoid賦給其他類型指(zhi)針,則(ze)需要強制類型轉換如(ru):

pint = (int *)pvoid; //轉換類型也就是(shi)獲得(de)指向(xiang)變量(liang)/對象大小

9.3 void指針不能復引用(即取內容的意思)

*pvoid //錯誤(wu)

要想復引(yin)用(yong)一個指針(zhen),或者(zhe)使用(yong)“->”運算符復引(yin)用(yong)一部(bu)分,都要有對于指針(zhen)指向的(de)內存的(de)解釋規(gui)則。

例如,int *p;

那(nei)么,當你后面復印用p的(de)時(shi)候,編譯(yi)器就(jiu)會把(ba)從p指向的(de)地址開(kai)始的(de)四個(ge)字節看作一(yi)個(ge)整數(shu)的(de)補碼(ma)。

因(yin)為void指針只知道指向(xiang)變量/對象(xiang)的起始地址(zhi),而不(bu)知道指向(xiang)變量/對象(xiang)的大小(占幾(ji)個字節)所以無(wu)法正確引(yin)用。

在(zai)實際的程序設計中,為迎合(he)ANSI標準(zhun),并提高(gao)程序的可移植性,我們可以這樣編寫實現同(tong)樣功能的代(dai)碼:

void*pvoid;

(char*)pvoid++; //ANSI:正確(que)(que);GNU:正確(que)(que)

(char*)pvoid+=1; //ANSI:錯誤;GNU:正確

上一篇:Java面試題(附答案)

下一篇:嵌入式C語言面試題大集合,都是自己總結的

熱點文章推(tui)薦
華清學員就(jiu)業榜單(dan)
高薪(xin)學員經驗分享
熱點新聞推(tui)薦
前臺專線:010-82525158 企業培訓(xun)洽談專線:010-82525379 院(yuan)校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部