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

當前位置:首頁 > 嵌入式培訓 > 嵌入式招聘 > 嵌入式面試題 > 嵌入式面試基本問(wen)題,各個都經(jing)典(dian)

嵌(qian)入式面試基本問(wen)題,各(ge)個都經典 時(shi)間(jian):2018-08-10      來(lai)源:未(wei)知

1 讀程序段,回答問題
(a)
int main(int argc,char *argv[])
{
int c=9,d=0;
c=c++%5;
d=c;
printf("d=%d\n",d);
return 0;
}
a) 寫出程序輸出
b) 在一個可移植的系統中這種表達式是否存在風險?why?
答案:5
存在風險,因為c=c++%5;這個表達式對c有兩次修改,行為未定義,c的值不確定
(b)
#include "stdio.h"
int a=0; // data section
int b; // data section
static char c; // BSS
int main(int argc,char *argv[])
{
char d=4; // stack
static short e; // BSS
a++;
b=100;
c=(char)++a;
e=(++d)++;
printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
return 0;
}
a) 寫出程序輸出
b) 編譯器如果安排各個變量(a,b,c,d)在內存中的布局(eg. stack,heap,data section,bss section),最好用圖形方式描述。
答案:a=2,b=100,c=2,d=6,e=5

2 中斷是嵌入式系統中重要的組成部分,這導致了許多編譯開發商提供一種擴展:讓標準C支持中斷,產生了一個新的關鍵字__interrupt。下面的代碼就使用了__interrupt關鍵字去定義了一個中斷服務子程序(ISR),請評論以下這段代碼。
__interrupt double compute_area(double radius)
{
double area = PI * radius *radius;
printf("nArea = %f", area);
return area;
}
答案
a)ISR不能返回一個值;
b)ISR不能傳遞參數;
c)浮點一般都是不可重入的;
d)printf函(han)數有重入和性能上的問題(ti)。

3 C/C++基礎知識問題
a) 關鍵字volatile在編譯時有什么含義?并給出三個不同使用場景的例子(可以偽代碼或者文字描述)。
用volatile關鍵字定義變量,相當于告訴編譯器,這個變量的值會隨時發生變化,每次使用時都需要去內存里
重新讀取它的值,并不要隨意針對它作優化。
建議使用volatile變量的場所:
(1) 并行設備的硬件寄存器
(2) 一個中斷服務子程序中會訪問到的非自動變量(全局變量)
(3) 多(duo)線程應用中被(bei)幾(ji)個任(ren)務共享的變量

b) C語言中static關鍵字的具體作用有哪些 ?
在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。
在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數
訪問。它是一個本地的全局變量。
在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的
模塊的本地范圍內使用。
static全局變量與普通的全局變量有什么區別:static全局變量只初使化一次,防止在其他文件單元中被引用;
static局部變量和普通局部變量有什么區別:static局部變量只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什么區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
c) 請問下面三種變量聲明有何區別?請給出具體含義
int const *p;
int* const p;
int const* const p;
答案
一個指向常整型數的指針
一個指向整型數的常指針
一個指向常整型(xing)數的常指針(zhen)

4 嵌入式系統相關問題
a) 對于整形變量A=0x12345678,請畫出在little endian及big endian的方式下在內存中是如何存儲的。
little endian big endian 剛好反過來
高地址--〉 0x12 低地址--〉 0x12
0x34 0x34
0x56 0x56
低地址--〉 0x78 高(gao)地址--〉 0x78

b) 在ARM系統中,函數調用的時候,參數是通過哪種方式傳遞的?
參數<=4時候,通過R0~R3傳遞(di),>4的(de)通過壓棧(zhan)方式傳遞(di)

c) 中斷(interrupt,如鍵盤中斷)與異常(exception,如除零異常)有何區別?
異常:在產生時必須考慮與處理器的時鐘同步,實踐上,異常也稱為同步中斷。在處理器執行到由于編程失誤而導致的錯誤指令時,或者在執行期間出現特殊情況(如缺頁),必須靠內核處理的時候,處理器就會產生一個異常。
所謂中斷應該是指外部硬件產生的一個電信號,從cpu的中斷引腳進入,打斷cpu當前的運行;
所(suo)謂異(yi)常,是指軟(ruan)件(jian)運行中發生(sheng)了一些必須作出處理的事件(jian),cpu自動產生(sheng)一個陷入來打斷(duan)當前運行,轉入異(yi)常處理流程(cheng)。

5 設周(zhou)期(qi)(qi)性(xing)任(ren)(ren)務(wu)P1,P2,P3的(de)周(zhou)期(qi)(qi)為T1,T2,T3分別為100,150,400;執(zhi)行(xing)(xing)時間分別為20,40,100。請設計一(yi)種(zhong)調度算(suan)法進(jin)行(xing)(xing)任(ren)(ren)務(wu)調度,滿足任(ren)(ren)務(wu)執(zhi)行(xing)(xing)周(zhou)期(qi)(qi)及任(ren)(ren)務(wu)周(zhou)期(qi)(qi)。

6 優先級反轉問題在嵌入式系統中是一中嚴重的問題,必須給與足夠重視。
a) 首先請解釋優先級反轉問題
b) 很多RTOS提供優先級繼承策略(Priority inheritance)和優先級天花板策略(Priority ceilings)用來解決優先級反轉問題,請討論這兩種策略。
高優先級任務需要等待低優先級任務釋放資源,而低優先級任務又正在等待中等優先級任務的現象叫做優先級反轉
優先級繼承策略(Priority inheritance):繼承現有被阻塞任務的最高優先級作為其優先級,任務退出臨界區,恢
復初始優先級。
優先級天花板策略(Priority ceilings):控制訪問臨界資源的信號量的優先級天花板。
優先級繼承策略對任務執行流程的影響相對教小,因為只有當高優先級任務申請已被低優先級任務占有的臨界資源
這(zhe)一事實發生時,才抬升低優先級(ji)任務的優先級(ji)。

預處理器(Preprocessor)

1 . 用預處理指令#define 聲明一個常數,用以表明1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
我在這想看到幾件事情:
1) #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等)
2)懂得預處理器將為你計算常數表達式的值,因此,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。
3) 意識到這個表達式將使一個16位機的整型數溢出-因此要用到長整型符號L,告訴編譯器這個常數是的長整型數。
4) 如果你(ni)(ni)(ni)在你(ni)(ni)(ni)的(de)表達式(shi)中用(yong)到UL(表示(shi)無符(fu)號長整型),那么你(ni)(ni)(ni)有(you)了一個好的(de)起(qi)點(dian)。記住,第一印象(xiang)很(hen)重(zhong)要。

2 . 寫一個"標準"宏MIN ,這個宏輸入兩個參數并返回較小的一個。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
這個測試是為下面的目的而設的:
1) 標識#define在宏中應用的基本知識。這是很重要的。因為在 嵌入(inline)操作符 變為標準C的一部分之前,宏是方便產生嵌入代碼的唯一方法,對于嵌入式系統來說,為了能達到要求的性能,嵌入代碼經常是必須的方法。
2)三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產生比if-then-else更優化的代碼,了解這個用法是很重要的。
3) 懂得在宏中小心地把參數用括號括起來
4) 我也用這個問題開始討論宏的副作用,例如:當你寫下面的代碼時會發生什么事?
least = MIN(*p++, b);

3. 預處理器標識#error的目的是什么?
如果你不(bu)(bu)知(zhi)道答(da)案(an),請看參考(kao)文獻1。這(zhe)問(wen)題對區(qu)分一(yi)個正(zheng)常的伙計(ji)和一(yi)個書呆(dai)子(zi)是很有用的。只有書呆(dai)子(zi)才(cai)會讀(du)C語言課本(ben)的附(fu)錄(lu)去(qu)找出(chu)象(xiang)這(zhe)種問(wen)題的答(da)案(an)。當然如果你不(bu)(bu)是在(zai)找一(yi)個書呆(dai)子(zi),那(nei)么應試(shi)者最好希望自己不(bu)(bu)要知(zhi)道答(da)案(an)。

死循環(Infinite loops)

4. 嵌入式系統中經常要用到無限循環,你怎么樣用C編寫死循環呢?
這個(ge)問題用(yong)幾個(ge)解(jie)決方(fang)案。我(wo)首選的方(fang)案是:

while(1)
{

}

一些程序員(yuan)更喜(xi)歡(huan)如(ru)下方案:

for(;;)
{

}

這(zhe)個(ge)(ge)(ge)(ge)實現方(fang)式讓我(wo)(wo)為(wei)難,因為(wei)這(zhe)個(ge)(ge)(ge)(ge)語法沒有確切表(biao)達到(dao)底怎么回(hui)事。如果一(yi)個(ge)(ge)(ge)(ge)應試者給出這(zhe)個(ge)(ge)(ge)(ge)作為(wei)方(fang)案,我(wo)(wo)將用(yong)這(zhe)個(ge)(ge)(ge)(ge)作為(wei)一(yi)個(ge)(ge)(ge)(ge)機會去探(tan)究他(ta)們(men)(men)這(zhe)樣做的基(ji)本(ben)(ben)原理。如果他(ta)們(men)(men)的基(ji)本(ben)(ben)答案是(shi):"我(wo)(wo)被(bei)教著這(zhe)樣做,但從沒有想到(dao)過為(wei)什么。&quot;這(zhe)會給我(wo)(wo)留下一(yi)個(ge)(ge)(ge)(ge)壞印(yin)象。

第三個方案是用 goto
Loop:
...
goto Loop;
應試(shi)者(zhe)如(ru)給出上(shang)面(mian)的方(fang)案,這(zhe)說明或(huo)(huo)者(zhe)他是(shi)一(yi)個(ge)匯編(bian)語言(yan)程(cheng)序員(yuan)(這(zhe)也許是(shi)好事)或(huo)(huo)者(zhe)他是(shi)一(yi)個(ge)想進入(ru)新領(ling)域的BASIC/FORTRAN程(cheng)序員(yuan)。

數據(ju)聲明(Data declarations)

5. 用變量a給出下面的定義
a) 一個整型數(An integer)
b)一個指向整型數的指針( A pointer to an integer)
c)一個指向指針的的指針,它指向的指針是指向一個整型數( A pointer to a pointer to an intege)r
d)一個有10個整型數的數組( An array of 10 integers)
e) 一個有10個指針的數組,該指針是指向一個整型數的。(An array of 10 pointers to integers)
f) 一個指向有10個整型數數組的指針( A pointer to an array of 10 integers)
g) 一個指向函數的指針,該函數有一個整型參數并返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一個(ge)(ge)有(you)10個(ge)(ge)指(zhi)針的數組,該指(zhi)針指(zhi)向一個(ge)(ge)函數,該函數有(you)一個(ge)(ge)整(zheng)型參(can)數并返(fan)回(hui)一個(ge)(ge)整(zheng)型數( An array of ten pointers to functions that take an integer argument and return an integer )

答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

人 們經常聲稱(cheng)這(zhe)(zhe)里有幾個問(wen)題(ti)是(shi)那種要翻一下(xia)書(shu)才能回答的(de)問(wen)題(ti),我(wo)(wo)同意這(zhe)(zhe)種說(shuo)法(fa)。當(dang)(dang)我(wo)(wo)寫這(zhe)(zhe)篇文章時,為(wei)了(le)確(que)定(ding)(ding)語法(fa)的(de)正確(que)性,我(wo)(wo)的(de)確(que)查了(le)一下(xia)書(shu)。但(dan)是(shi)當(dang)(dang)我(wo)(wo)被(bei)面試(shi)(shi) 的(de)時候,我(wo)(wo)期望被(bei)問(wen)到這(zhe)(zhe)個問(wen)題(ti)(或(huo)者相近的(de)問(wen)題(ti))。因為(wei)在被(bei)面試(shi)(shi)的(de)這(zhe)(zhe)段時間里,我(wo)(wo)確(que)定(ding)(ding)我(wo)(wo)知(zhi)道(dao)這(zhe)(zhe)個問(wen)題(ti)的(de)答案。應(ying)試(shi)(shi)者如果不知(zhi)道(dao)所有的(de)答案(或(huo)至少(shao)大部分答 案),那么(me)也就(jiu)沒有為(wei)這(zhe)(zhe)次面試(shi)(shi)做(zuo)準(zhun)備,如果該面試(shi)(shi)者沒有為(wei)這(zhe)(zhe)次面試(shi)(shi)做(zuo)準(zhun)備,那么(me)他又能為(wei)什么(me)出準(zhun)備呢?

Static

6. 關鍵字static的作用是什么?
這個簡單的問題很少有人能回答完全。在C語言中,關鍵字static有三個明顯的作用:
1)在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。
2) 在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。
3) 在模(mo)塊內,一(yi)(yi)個被聲明為靜態的(de)函(han)數(shu)只(zhi)可被這一(yi)(yi)模(mo)塊內的(de)其它函(han)數(shu)調用。那(nei)就是,這個函(han)數(shu)被限制在聲明它的(de)模(mo)塊的(de)本地(di)范圍內使用。

大多數應試(shi)(shi)者能(neng)正確回答(da)第(di)一(yi)部分,一(yi)部分能(neng)正確回答(da)第(di)二部分,同是很少的人能(neng)懂(dong)得(de)第(di)三部分。這是一(yi)個應試(shi)(shi)者的嚴重的缺(que)點,因(yin)為(wei)他顯然(ran)不(bu)懂(dong)得(de)本地化數據和(he)代碼范圍的好(hao)處和(he)重要性。

Const

7.關鍵字const有什么含意?
我 只要一聽到被面試者說:"const意味著常數",我就知道我正在和一個業余者打交道。去年Dan Saks已經在他的文章里完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應該非常熟悉const能做什么和不能做什么.如果你從沒有讀到那篇文章,只要能說出const意味著"只讀"就可 以了。盡管這個答案不是完全的答案,但我接受它作為一個正確的答案。(如果你想知道更詳細的答案,仔細讀一下Saks的文章吧。)
如果應試者能正確回答這個問題,我將問他一個附加的問題:
下面(mian)的聲(sheng)明都是(shi)什么意思?

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

/******/
前 兩個的作用是一樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針可以)。第四個意思a是一個指向整型 數的常指針(也就是說,指針指向的整型數是可以修改的,但指針是不可修改的)。最后一個意味著a是一個指向常整型數的常指針(也就是說,指針指向的整型數 是不可修改的,同時指針也是不可修改的)。如果應試者能正確回答這些問題,那么他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關鍵字 const,也還是能很容易寫出功能正確的程序,那么我為什么還要如此看重關鍵字const呢?我也如下的幾下理由:
1) 關鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,實際上,聲明一個參數為常量是為了告訴了用戶這個參數的應用目的。如果你曾花很多時間清理 其它人留下的垃圾,你就會很快學會感謝這點多余的信息。(當然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)
2) 通過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。
3) 合(he)理地使用關鍵字const可以使編譯器很自然地保護那(nei)些不希望被(bei)改(gai)變的參數,防止其被(bei)無意的代碼修改(gai)。簡而(er)言之,這樣可以減少bug的出現(xian)。

Volatile

8. 關鍵字volatile有什么含意?并給出三個不同的例子。
一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個例子:
1) 并行設備的硬件寄存器(如:狀態寄存器)
2) 一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
3) 多線程(cheng)應用中被幾個任務共享的(de)變(bian)量

回答不出這個問題的人是不會被雇傭的。我認為這是區分C程序員和嵌入式系統程序員的最基本的問題。搞嵌入式的家伙們經常同硬件、中斷、RTOS等等打交道,所有這些都要求用到volatile變量。不懂得volatile的內容將會帶來災難。
假設被面試者正確地回答了這是問題(嗯,懷疑是否會是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。
1)一個參數既可以是const還可以是volatile嗎?解釋為什么。
2); 一個指針可以是volatile 嗎?解釋為什么。
3); 下面的函(han)數有(you)什么(me)錯誤:

int square(volatile int *ptr)
{
return *ptr * *ptr;
}

下面是答案:
1)是的。一個例子是只讀的狀態寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它。
2); 是的。盡管這并不很常見。一個例子是當一個中服務子程序修該一個指向一個buffer的指針時。
3) 這段代碼有點變態。這段代碼的(de)(de)目的(de)(de)是(shi)用來返指針(zhen)*ptr指向值的(de)(de)平方(fang),但(dan)是(shi),由于*ptr指向一個volatile型(xing)參數,編譯器將(jiang)產生類(lei)似下面(mian)的(de)(de)代碼:

int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}

由于(yu)*ptr的值(zhi)可(ke)能被意想不(bu)(bu)到地該變,因此a和b可(ke)能是不(bu)(bu)同的。結果,這段代碼可(ke)能返(fan)不(bu)(bu)是你所期望的平(ping)方值(zhi)!正確的代碼如下:

long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

位操作(Bit manipulation)

9. 嵌入式系統總是要用戶對變量或寄存器進行位操作。給定一個整型變量a,寫兩段代碼,第一個設置a的bit 3,第二個清除a 的bit 3。在以上兩個操作中,要保持其它位不變。
對這個問題有三種基本的反應
1)不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。
2) 用bit fields。Bit fields是被扔到C語言死角的東西,它保證你的代碼在不同編譯器之間是不可移植的,同時也保證了的你的代碼是不可重用的。我最近不幸看到 Infineon為其較復雜的通信芯片寫的驅動程序,它用到了bit fields因此完全對我無用,因為我的編譯器用其它的方式來實現bit fields的。從道德講:永遠不要讓一個非嵌入式的家伙粘實際硬件的邊。
3) 用 #defines 和(he) bit masks 操作。這(zhe)是(shi)一個有極高可移植(zhi)性(xing)的(de)方(fang)(fang)法,是(shi)應該被用到的(de)方(fang)(fang)法。最佳的(de)解決方(fang)(fang)案如下:

#define BIT3 (0x1 << 3)
static int a;

void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &= ~BIT3;
}

一(yi)些人喜歡為設(she)置和清(qing)除值(zhi)而定義一(yi)個(ge)掩碼同時定義一(yi)些說明常數,這也(ye)是可以接受(shou)的(de)。我(wo)希望(wang)看(kan)到幾個(ge)要點:說明常數、|=和&=~操作(zuo)。

訪問固定的內存位置(zhi)(Accessing fixed memory locations)

10. 嵌入式系統經常具有要求程序員去訪問某特定的內存位置的特點。在某工程中,要求設置一絕對地址為0x67a9的整型變量的值為0xaa66。編譯器是一個純粹的ANSI編譯器。寫代碼去完成這一任務。
這一問題測試你是否知道為了訪問一絕對地址把一個整型數強制轉換(typecast)為一指針是合法的。這一問題的實現方式隨著個人風格不同而不同。典型的類似代碼如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;

A more obscure approach is:
一(yi)個較晦(hui)澀的方法是:

*(int * const)(0x67a9) = 0xaa55;

即使你的品味更(geng)接近第二種方(fang)案(an),但(dan)我建議你在面試時使用第一種方(fang)案(an)。

中(zhong)斷(duan)(Interrupts)

11. 中斷(duan)(duan)是嵌入式(shi)系統中重(zhong)要(yao)的(de)(de)(de)組成部(bu)分,這導致了很(hen)多編(bian)譯開發商(shang)提供一種擴(kuo)展—讓標準C支持中斷(duan)(duan)。具代(dai)表事實是,產(chan)生了一個新的(de)(de)(de)關(guan)鍵字 __interrupt。下面的(de)(de)(de)代(dai)碼(ma)就使用了__interrupt關(guan)鍵字去定義了一個中斷(duan)(duan)服務子程序(ISR),請評(ping)論一下這段代(dai)碼(ma)的(de)(de)(de)。

__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}

這個函數有太多的錯誤了,以至讓人不知從何說起了:
1)ISR 不能返回一個值。如果你不懂這個,那么你不會被雇用的。
2) ISR 不能傳遞參數。如果你沒有看到這一點,你被雇用的機會等同第一項。
3) 在許多的處理器/編譯器中,浮點一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點運算。此外,ISR應該是短而有效率的,在ISR中做浮點運算是不明智的。
4) 與第(di)三點(dian)(dian)一脈相承,printf()經(jing)常有重入和(he)性(xing)能(neng)上的問題(ti)。如果(guo)你(ni)丟掉了第(di)三和(he)第(di)四點(dian)(dian),我(wo)不會太為難你(ni)的。不用(yong)說,如果(guo)你(ni)能(neng)得(de)到后兩(liang)點(dian)(dian),那(nei)么你(ni)的被(bei)雇用(yong)前(qian)景越(yue)來(lai)越(yue)光明了。

代碼(ma)例子(Code examples)

12 . 下面的代(dai)碼輸出是什么(me),為什么(me)?

void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") : puts("<= 6");
}
這 個(ge)問(wen)題(ti)(ti)測試你(ni)是否懂(dong)(dong)得C語言中的(de)(de)整(zheng)數自動(dong)轉(zhuan)換原則,我發現有些(xie)開發者(zhe)懂(dong)(dong)得極少這些(xie)東西。不(bu)管(guan)如何,這無(wu)符(fu)(fu)號整(zheng)型(xing)問(wen)題(ti)(ti)的(de)(de)答案是輸出是 ">6"。原因是當表達(da)式(shi)中存在有符(fu)(fu)號類型(xing)和無(wu)符(fu)(fu)號類型(xing)時所(suo)有的(de)(de)操作數都自動(dong)轉(zhuan)換為無(wu)符(fu)(fu)號類型(xing)。因此(ci)-20變成了一(yi)個(ge)非常(chang)(chang)大的(de)(de)正整(zheng)數,所(suo)以該表達(da)式(shi) 計算(suan)出的(de)(de)結果大于(yu)6。這一(yi)點對于(yu)應(ying)當頻繁(fan)用到(dao)無(wu)符(fu)(fu)號數據類型(xing)的(de)(de)嵌入式(shi)系統來說是豐常(chang)(chang)重要的(de)(de)。如果你(ni)答錯了這個(ge)問(wen)題(ti)(ti),你(ni)也(ye)就到(dao)了得不(bu)到(dao)這份工(gong)作的(de)(de)邊緣。

13. 評(ping)價下(xia)面的代碼片斷:

unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */

對(dui)于(yu)一個int型(xing)不(bu)是(shi)16位的處理器(qi)為說,上面的代碼(ma)是(shi)不(bu)正確的。應編寫如下:

unsigned int compzero = ~0;

這一問題真正能揭露出應試者是否懂得處理器字長的重要性。在我的經驗里,好的嵌入式程序員非常準確地明白硬件的細節和它的局限,然而PC機程序往往把硬件作為一個無法避免的煩惱。
到 了這(zhe)(zhe)(zhe)個階(jie)段,應(ying)(ying)試(shi)者(zhe)(zhe)(zhe)或者(zhe)(zhe)(zhe)完(wan)全垂頭(tou)喪氣了或者(zhe)(zhe)(zhe)信心(xin)滿(man)滿(man)志在必得(de)。如(ru)果顯然應(ying)(ying)試(shi)者(zhe)(zhe)(zhe)不(bu)是很好,那(nei)么這(zhe)(zhe)(zhe)個測試(shi)就(jiu)在這(zhe)(zhe)(zhe)里結束了。但如(ru)果顯然應(ying)(ying)試(shi)者(zhe)(zhe)(zhe)做得(de)不(bu)錯,那(nei)么我就(jiu) 扔出(chu)下面的(de)追加問(wen)題(ti)(ti),這(zhe)(zhe)(zhe)些(xie)問(wen)題(ti)(ti)是比較難的(de),我想僅(jin)僅(jin)非常優秀的(de)應(ying)(ying)試(shi)者(zhe)(zhe)(zhe)能做得(de)不(bu)錯。提出(chu)這(zhe)(zhe)(zhe)些(xie)問(wen)題(ti)(ti),我希望(wang)更多(duo)看(kan)到應(ying)(ying)試(shi)者(zhe)(zhe)(zhe)應(ying)(ying)付問(wen)題(ti)(ti)的(de)方法,而不(bu)是答案。不(bu)管如(ru) 何,你就(jiu)當是這(zhe)(zhe)(zhe)個娛樂吧...

動態內存分(fen)配(pei)(Dynamic memory allocation)

14. 盡管不像非嵌入式計算機那么常見,嵌入式系統還是有從堆(heap)中動態分配內存的過程的。那么嵌入式系統中,動態分配內存可能發生的問題是什么?
這 里,我期望應試者能提到內存碎片,碎片收集的問題,變量的持行時間等等。這個主題已經在ESP雜志中被廣泛地討論過了(主要是 P.J. Plauger, 他的解釋遠遠超過我這里能提到的任何解釋),所有回過頭看一下這些雜志吧!讓應試者進入一種虛假的安全感覺后,我拿出這么一個小節目:
下面(mian)的代碼(ma)片段的輸出是(shi)什么,為(wei)什么?

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");

這(zhe)(zhe) 是(shi)一個(ge)有(you)趣(qu)的(de)問(wen)(wen)(wen)(wen)題。最近在我(wo)的(de)一個(ge)同事不經意把0值傳給了(le)函數malloc,得到(dao)了(le)一個(ge)合法的(de)指(zhi)針之(zhi)后,我(wo)才想到(dao)這(zhe)(zhe)個(ge)問(wen)(wen)(wen)(wen)題。這(zhe)(zhe)就(jiu)是(shi)上面的(de)代碼,該代碼的(de)輸(shu) 出是(shi)"Got a valid pointer"。我(wo)用這(zhe)(zhe)個(ge)來開始討論這(zhe)(zhe)樣(yang)的(de)一問(wen)(wen)(wen)(wen)題,看看被面試者(zhe)是(shi)否想到(dao)庫例程這(zhe)(zhe)樣(yang)做是(shi)正(zheng)確。得到(dao)正(zheng)確的(de)答案固然重要,但(dan)解決問(wen)(wen)(wen)(wen)題的(de)方法和你(ni)做決定的(de)基(ji) 本原理更重要些。

Typedef
15 Typedef 在C語言中頻繁用(yong)以聲明(ming)一個(ge)已(yi)經(jing)存在的(de)數據類型(xing)的(de)同義字(zi)。也可以用(yong)預處(chu)理器(qi)做類似的(de)事(shi)。例如,思(si)考一下(xia)下(xia)面(mian)的(de)例子(zi):

#define dPS struct s *
typedef struct s * tPS;

以上兩種情況的意圖都是要定義dPS 和 tPS 作為一個指向結構s指針。哪種方法更好呢?(如果有的話)為什么?
這(zhe)(zhe)是(shi)(shi)一個非常微妙的問(wen)題,任何人答對這(zhe)(zhe)個問(wen)題(正當的原因)是(shi)(shi)應當被恭喜(xi)的。答案是(shi)(shi):typedef更好(hao)。思考(kao)下面的例子:

dPS p1,p2;
tPS p3,p4;

第一個擴展為

struct s * p1, p2;
.
上(shang)面的(de)代碼定義p1為一個(ge)指向結(jie)構(gou)的(de)指,p2為一個(ge)實際的(de)結(jie)構(gou),這(zhe)也許不(bu)是你想要(yao)的(de)。第二個(ge)例子正確(que)地定義了p3 和p4 兩個(ge)指針。

晦澀的語法

16 . C語言(yan)同意(yi)一些(xie)令(ling)人(ren)震(zhen)驚的結構,下面的結構是(shi)合法的嗎,如果是(shi)它做些(xie)什么(me)?

int a = 5, b = 7, c;
c = a+++b;

這(zhe)個問(wen)題將做為這(zhe)個測驗的(de)(de)(de)(de)一個愉快的(de)(de)(de)(de)結(jie)尾。不管(guan)你(ni)相(xiang)不相(xiang)信,上(shang)面的(de)(de)(de)(de)例子是完全合乎語法(fa)的(de)(de)(de)(de)。問(wen)題是編譯器如何處(chu)(chu)理它?水平不高(gao)的(de)(de)(de)(de)編譯作(zuo)者(zhe)實際上(shang)會(hui)爭論這(zhe)個問(wen)題,根據最處(chu)(chu)理原則,編譯器應當能處(chu)(chu)理盡可(ke)能所有合法(fa)的(de)(de)(de)(de)用(yong)法(fa)。因此,上(shang)面的(de)(de)(de)(de)代碼(ma)被處(chu)(chu)理成:

c = a++ + b;

因此, 這段代碼持行后a = 6, b = 7, c = 12。
如(ru)果你知道答案,或猜(cai)出(chu)正確答案,做得好(hao)。如(ru)果你不知道答案,我(wo)也(ye)不把(ba)這個(ge)當作(zuo)問(wen)題。我(wo)發現這個(ge)問(wen)題的(de)最(zui)大好(hao)處是這是一個(ge)關于代碼(ma)(ma)編寫風格(ge),代碼(ma)(ma)的(de)可讀性(xing),代碼(ma)(ma)的(de)可修改性(xing)的(de)好(hao)的(de)話題。

上一篇:嵌入式操作系統面試題拿在手,面試通通不懼

下一篇:千家公司嵌入式面試題,都是比較常見的

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

回到頂部