C語言測試:嵌入式程序員必須知道的16個問題_第1頁
C語言測試:嵌入式程序員必須知道的16個問題_第2頁
C語言測試:嵌入式程序員必須知道的16個問題_第3頁
C語言測試:嵌入式程序員必須知道的16個問題_第4頁
C語言測試:嵌入式程序員必須知道的16個問題_第5頁
全文預覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、C語言測試:嵌入式程序員必須知道的16個問題pcbomb發(fā)表于2008-10-9 13:39:00閱讀全文(1981) |回復(2) |引用通告(0) |編輯C涪靑測試是招聘嵌入式系統(tǒng)程序員過程中必須而吐右效的方法這些年.我既參加也組織了許多這種測試.在這過程中我意識到這些測試能為帶仰 試者和被面試昔提供有用信息此勾| 開面試的壓力不談,這種測試也是相當有趣的.從被面試者的角度來講.你能了解許多關(guān)于出題打或監(jiān)考者的怙況。這個測試只是出題咅為顯示其對ANSI標準細節(jié)的知識而不足技術(shù)技巧而設(shè)計 嗎?這個愚盤的問題嗎?如耍你存出某個7符的ASCII你 這些問題科飛考察你的系統(tǒng)調(diào)川和內(nèi)存分配策略方而的

2、能力嗎?這標店行出題冷也許花時 間倉微機上而不上在嵌入式系統(tǒng)上如果上述任何問觀的答案是 沁 的話.那么我知道我得認真考慮我是否應(yīng)該去做這份匸作。從面試者的角度來兒 個測試也許能從多方面羯示應(yīng)試者的素質(zhì):最基本的.你能了解應(yīng)試#Ci»W的水平.不管怎么樣.看一下這人如何回答他 不會的問題也是滿仃趣°應(yīng)試右圧以好的血覺做出明智的選擇還是只是瞎蒙呢?十應(yīng)試者住某個問題上t住時是找借口呢.還是衣現(xiàn)出對問題的貞 止山J j心.把這看甘 習的機會呢.,2現(xiàn)這些信息打他們的測試成績TY仃心有這些想法.我決定出-些貞止針對嵌入式系統(tǒng)的考題.希望這些令人頭病的不題能給止在找1 作的人一點幫住

3、。這些紂題都是我這些年實際碰到 的幾中有些題很難.但它們應(yīng)該者】你一點啟迪這個測試適于不同水平的應(yīng)試者.大藝數(shù)初級水平的應(yīng)試者的成績會很差.經(jīng)驗豐富的程序員應(yīng)該有很好的成績。為了il你能fl己決定某些問題的偏 好.每個問題沒有分配分數(shù).如果選擇這些考遡為你所用.請n行按你的意思分配分數(shù)預處理器(Preprocessor)1 .用橫處理指令字define聲期一個常數(shù),用以農(nóng)明1年中有多少秒(忽略閏年問題)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL我在這想看到兒件痕祜:?;#define講法的皐木知識(例如:不能以分號結(jié)束.括號的使用,等等)?;

4、懂得預處理器將為你汁算常數(shù)表達式的值.因此.直接寫出你是如何計算一年中有多少秒而不是計算出實際的值是更淸晰而沒仃代價的.?;怠識到這個茨達式將使個"位機的卻效溢出內(nèi)此翌用到長整盤符號L啟訴編譯畧這個常數(shù)足的長整蛋?;如果你在你的衣達式中用到UL (表示無符號長笹型).那么你冇了一個好的起點.記住.第-卬象很亜耍.2 坷一個“標準宏MIN 這個宏輸入兩個參數(shù)并返回較小的一個#define MIN(A,B) < (A) <= (B) ? (A) : (B)這個測試是為卜托】的目的而設(shè)的:?;林識孝define作宏中間H的堆木illilL這 旻的.兇為W到嵌入(inline)操

5、作符變?yōu)闃嘶碈的一部分.丿便產(chǎn)牛嵌入代碼的唯一方沃.Xj J-嵌入式系統(tǒng)來說.為了能達到要求的性能.嵌入代碼經(jīng)常是必須的方法。?;三匝條件操作符的知識這個操作符存在cmn中的原因是它使得編禪益能產(chǎn)t比if-then-elself優(yōu)化的代碼.了解這個川法是很禾雯的.?;懂得在宏屮小心地把參數(shù)用括號折起來?;我也用這個問題開始討論宏的副作用,例如,出你耳F面的代碼時會發(fā)生什么事?least = MIN(*p+r b);3.偵處理器標識#error(rj目的是什么?如果你不知道答案.請看參考文獻這問題對區(qū)分一個世常的伙計和一個書呆子是很有用的。只有書呆子才會讀Cift言課木的附錄去找出彖這沖何 題的

6、答案.十然如果你不是在找一個書呆子那么應(yīng)試者最好希里自己不要知道答紜死循環(huán)(Infinite loops)4i茨入式系統(tǒng)中經(jīng)常炎用到無隔循環(huán)你怎么樣川C編丐死循環(huán)呢?這個何題用幾個解決方冬。我IT選的方案足:while(l)?一些程用員処喜炊如卜方案:for(;<?這個實現(xiàn)方式訃我為暗因為這個語法沒冇確切衣達到底怎么冋弔.如來 個應(yīng)試不給出這個作為方案.我將用這個作為-個機會去探究他們這樣做 的尿木原理。如果他們的肚木答案足:“我被教著這樣做.但從沒冇想到過為什么”這會給我冊下一個壞卬線菽三個方案是用gotoLoop: goto Loop;應(yīng)試者如給出匕衍的方案.這說明或音他是 個匯編說

7、吉程序員(這也許是好半)或者他是一個想進入新領(lǐng)域的BASIC/FORTRAN用序員。數(shù)據(jù)聲明(Data declarations)5. 用變址a給出下面的定義a) 個整?0數(shù)(An integer)b) 個拒向幣型數(shù)的拆什(A pointer to an integer)cj 個后向扌旨針的的扌斤針,它聃向的描什是Bi向-個整型數(shù)(A pointer to a pointer to an intege) rd) 個右10個整型數(shù)的數(shù)組(An array of 10 integers)e) 一個竹10個拆針的數(shù)組該捋針是指向一個整型數(shù)的 (An array of 10 pointers to i

8、ntegers)f) 一個折向冇10個整型數(shù)數(shù)組的指針(A pointer to an array of 10 integers)g) 個折向鬲數(shù)的扌&針該說藪看一個幣和參數(shù)并返I叫一個整巾數(shù)(A pointer to a function that takes an integer as an argument and returns a n integer)h) 個“10個折什的ft該拆針拆向個函數(shù).該甬數(shù)仆 個怡型參數(shù)并返冋-個整別數(shù)(An array of ten pointers to functions that take an i nteger argument and

9、return an integer )答案iha) int a; / An integerb) int *a; / A pointer to an integerc) int *a; / A pointer to a pointer to an integerd) int a10; / An array of 10 integerse) int *a10; / An array of 10 pointers to integersf) int (F)10; / A pointer to an array of 10 integersg) int (*a)(int); / A pointer t

10、o a function a that takes an integer argument and returns an integerh) int (*a10)(int); / An array of 10 pointers to functions that take an integer argument and return an integer人們經(jīng)常術(shù)稱這里仃幾個何題是那種耍翻 下祐才能冋答的問題.我同意這種說法十我9這篇文傘時.為了倆定語法的正確性.我的確件了-下 H.但是出我被面試的時候,我期望被問到這個問題(或者相近的問題).因為在被面試的這段時間里.我確定我知道這個問題的答

11、案應(yīng)試者如果 不知道所仃的答案(或至少大部分答案那么也就沒仃為這次面試做準備.如果該ifiiiAA沒仃為這次ihi試做準備那么他乂能為什么生準備呢? Static6. 關(guān)鍵字static的作用是什么?這個簡單的問題很少佇人能冋答完全。在Ci弁言中,關(guān)鍵字static有三個明眾的作用:?;在函數(shù)體.一個被聲明九靜態(tài)的變址在這函效被調(diào)用過程中維持其值不變?; 4模塊內(nèi)(但在函數(shù)沐外) Z - 10為靜態(tài)的増可以被模塊內(nèi)所用西數(shù)訪皿 但不能被模塊外梵它函數(shù)訪問它是個本地的全局交量 ?;4模塊內(nèi).個被聲明為眇念的聞數(shù)只町被這 模塊內(nèi)的其它函數(shù)調(diào)用。那就血 這個函數(shù)被限制在聲明它的模塊的木地范田內(nèi)使川:

12、人參敷山試擰廃止確1:二 分.一部分能正確回答第二薄分,同見很少的人能値得第三部分。送是一個應(yīng)試擰的嚴亟的缺點閔為他顯然不懂得 木地化數(shù)據(jù)和代碼范國的好處和巫耍性.Const7. 關(guān)鍵字const有什么含意?我只雯一聽到被面試者說:"onst意味著常數(shù)* 我就知道我正在和一個業(yè)余者打交道。去年Dan Saks已經(jīng)在他的文吊里完全槪括了const的所有 用法因此ESP(i*者:Embedded Systems Programming)的毎一位讀和2該II常熟悉const能做什么和不能做什么如果你從沒冇讀到那篇文去.只 翌能說出const遼味著“只讀”就可以了。盡管這個答條不足完全的答案

13、.但我接受它作為-個正確的答案(如果你想知道更詳細的答案.仔細讀 一 bSaks的文蘋吧。)如果應(yīng)試音能止確回答這個何題.我將問他-個附加的問理下面的聲明都是什么意恩?const int a;int const a;const int *a;int * const a;int const * a const;/導*$ par /前兩個的作用是i樣.a足一個常整取數(shù)。第三個盤味若a址i個折向常掘型數(shù)的扌Rf|(也就址.笹巾數(shù)是不可修改的.但抬針可以)滾四個意思a 足 個指向整型數(shù)的常折針(也"1 粉措向的整矗霞是可以修改的.但時是不可修改的八量后一個意味彳2X 個折向常整型數(shù)的簾拆什(

14、也就是說.指針指向的整型數(shù)是不可修改的同時指針也是不可修改的).如果應(yīng)試右能止確回答這些問題,那么他就給我留下了 個好卬敘順 帯提一句,也許你可能會軻,即使不用關(guān)健? const-也還是能很容易寫出功能正確的程序,那么我為什么還嬰如此Cconst呢?我也如卜. 的幾下理由:?;共鍵字const的作用是丸你代碼的人傳達香常有用的佶息實際匕.聲明一個參數(shù)為常fit是為了告訴了用戶這個參數(shù)的應(yīng)用目的.如果你忡花很藝時間淸理其它人陽下的垃圾.你就會很快學會感謝這點多余的信息("然懂得用const的程序員很少會留下的垃圾訃別人來淸理的. ?;通過給優(yōu)化器些附加的仁息使用關(guān)鍵字const也許能產(chǎn)

15、工更緊湊的代碼.?;會理地使川關(guān)鍵/constnJ以便編劇*很fl然地保護那被改變的參肌 防止H被無怠的代們恢”(簡而:這樣町以減少bug的;I現(xiàn)。 Volatile8. 關(guān)鍵字volatile什么含意?并給出三個不同的例譏個定義為volatile的變雖是說這變址可能會被怠想不到地改變.這樣.編譯器就不會去假設(shè)這個變址的值幾 粘確地說就是.優(yōu)化器在用到這個變 量時必欠都小心地取新讀取這個變址的們.而不是使用保存在寄存器里的備份.F面是volatile變址的幾個例f:?;并行設(shè)備的皎件寄存器(如:狀態(tài)寄存器)?;個中斷服務(wù)(程序卞會訪何到的IFH動變(Non-automatic variable

16、s)?;多鏡程應(yīng)用中被幾個任錚共享的回答不出這個何題的人是不會被麗傭的我認為這是區(qū)dCRFE和嵌入式系統(tǒng)程序員的域叢木的問題.搞嵌入式的家伙們經(jīng)Shdiil!件、中阪RTO S等等打交道.所仃這些都雯求用到volatile變址。不懂得volatile的內(nèi)容將會帯來災(zāi)瓠假設(shè)被面試者止確地冋答這是問題(哩.懷疑是竹會是這樣),我將稍微深究一卜.看一卜這家伙是不是貝止懂得volatile完全的匝要性。?; 一個參數(shù)既町以是const還可以是volatile嗎?解秣為什么“?; 一個指什可以是volatile嗎?解釋為什么?;下面的函數(shù)冇什么tttiX:int square(volatile int

17、*ptr)<return wptr * *ptr;F面是答案:?;是的.一個例"是只請的狀態(tài)崙存器.它是volXilQl對為它對能被息想不到地改變它是const因為親序不應(yīng)該試閣去修改它.?;是的。盡管這并不很常也一個例子是X個中服務(wù)子程序修該一個折向一個buffer的指針時。二,2代碼仃點變態(tài)這段代碼的丨丨的址川來返折針Str指向值的平方.但是山JStr折向個volatile型參數(shù).編譯器將廣牛艾似卜面的代碼*int square(volatile int *ptr)<int a,b;a = *ptr;b = *ptr;return a b;由于Str的值町能被危想不到

18、地該變.因此a和b可能是不同的。結(jié)果,這段代碼對能返不是你所期望的平方值!止確的代碼如卜:long square(volatile int *ptr)<int a;a = *ptr;return a w a;位操作(Bit manipulation)9. i校入式系統(tǒng)總是嬰川門對變址或寄存器進彳丁位操作二給定* 盤受量a嗎兩段心1第一個設(shè)置a的bit 3.第二個清除a的bit 3。在以上兩個 操作中嬰保持其它位不變。對這個問題有三種基木的反應(yīng)?;不丸I道如何卜Fc該坡面者從沒做過任何嵌入式系統(tǒng)的I作:?;用bit fields Bit fields足被扔到CWW死角的東西.它保證你的代碼

19、在不同編譯署之間是不可移植的.同時也保證了的你的代碼是不可第用的我 眾近不幸看到Infineon為其較復朵的通信芯片G的驅(qū)動和序.它用到了bit fieldsW此完仝對我無用.因為我的編譯器用氏它的方式來實現(xiàn)bit fields 的.從道徳講:水遠不耍讓個II衣入式的家伙粘實際破件的邊。?;川育血fines和bit masks操作。這是個仃極高可移樓性的方込 是應(yīng)該被川到的方法.域佳的解決方案如下:孝define BIT3 (0x1 << 3)static int a;void set_bit3(void) a |= BIT3;void clear_bit3(void) a &am

20、p;= BIT3;些人喜歡為設(shè)貰和淸除(ft而定義一個掩碼同時定義-些說明常數(shù).這也足可以接爻的.我希望看到幾個要點:說明常數(shù).匸和&=操作.訪問尚定的內(nèi)存位總(Accessing fixed memory locations)10嵌入式系統(tǒng)經(jīng)常八竹耍求程序員決訪問臬伯淀的內(nèi)存位置的特點。止菜I.程中.咚求垃黃絕對地址為0x67a9的整型變址的值為0xaa66B編訐 簽是-個純粹的ANSI編譯器。弓代碼去完成這-任務(wù)。這一問題測試你是否知道為了訪何絕對地址把一個整盤數(shù)強制軋換(typecast)為一指針是合法的.這何題的實現(xiàn)方式蘆著個人風格不同而不 同.典和的類似代碼如下:int *p

21、tr;ptr = (int *)0x67a9;*ptr = 0xaa55;A more obscure approach is:個較蹲澀的方法匹*(int * const)(0x67a9) = 0xaa55;即使你的乩味更接近笫二種方案.但我建議你在面試時便用第種方案中新(Interrupts)11 屮斷是嵌入式系統(tǒng)中腹翌的紐成部分.這導致了很多編譯開發(fā)商提供 種擴展一訃標準C支持中斷。具代農(nóng)爭實是,產(chǎn)生了一個新的關(guān)鍵字_in terrupt.下面的代碼就使用了_interrupt關(guān)惟字去定義了一個中斷脳務(wù)子程序(ISR).請評論一下這段代碼的。_interrupt double comput

22、e.area (double radius)<double area = PI * radius * radius;printf(MnArea = %f area);return area;這個換數(shù)仃太女的錯課了.以至讓人不知從何說起了?; ISR不能逖回一個值.如采你不11這個那么你不會被巔用的.?;ISR不能傳遞鑫數(shù)。如果你沒的看到這點你被熾用的機會等同第一項。?;在許多的處理辭/編H器中浮點般都是不可重入的。有些處理器/編悴器需嬰辻額處的寄存容入棧,處理器/編譯譽庶是不允許在ISR中做 浮點運算.此外 ISR應(yīng)該是短而有效率的.在ISR中做浮點運算是不明智的。?;與第二點一脈相承.

23、printfO紐常有重入和性能上的何題如果你去掉了第三和第四點.我不會太為難你的.不用說如果你能得到示兩點那么 你的被麻用前彊越來越光明了。代碼例(Code examples)12卜的代碼輸山是什么.為什么?void foo(void)unsigned int a = 6;int b = -20;(a+b > 6) ? puts(M> 6") : puts("<= 6M);這個何題測試你是否懂得C語言中的酸數(shù)門動轉(zhuǎn)換原則.我發(fā)現(xiàn)冇些開發(fā)者懂得極少這些東限 不管如何.這無符號簾住問題的答案足輸出是-> 6".廩因是為表達式中存在有符號類型和無

24、符號類盤時所有的播作效都自動轉(zhuǎn)換為于類型因此20變戌了一個血常大的正整數(shù),所以該表達式計算出的結(jié)果大于6.這一點對于應(yīng)當頻繁用到無符號數(shù)據(jù)類型的嵌入式系統(tǒng)來說是豐常重婆的。如果你答錯了這個問題.你也就到了得不到這份1: 作的邊緣。13.評價£面的代碼片斷:unsigned int zero = 0;unsigned int compzero = OxFFFF;/*l's complement of zero */對于一個int空不是16位的處理器為說.上血的代碼是不正確的.應(yīng)編丐如下:unsigned int compzero = 0;這-何題直正能掏濾出應(yīng)試打是否懂得處理器

25、字K的豆耍性.在我的經(jīng)驗甲好的嵌入式程序員II常準確地明門換件的細節(jié)和它的局限.然而PC機 程序往往把碩件作為個無仏避免的煩惱到了這個階段應(yīng)試不或者完全垂頭喪氣了或音仿心満満怎在必得。如果顯然應(yīng)試/不見很好.那么這個測試就在這里納柬了.但如果顯然應(yīng)迖者做 得不錯屎么我就扔出下面的追加何題.這些問&址比較難的.我想僅僅非常優(yōu)秀的應(yīng)試者能做得不錯。提出這些問題.我希望更多看到應(yīng)試者陽J 旦題的方法.而不是答案。不管如何.你就十是這個娛處吧動態(tài)內(nèi)存分配(Dynamic memory allocation)14盡伶不像非攸入式計并機那么常犯.飮入式系統(tǒng)還是有從堆(heap)屮動態(tài)分配內(nèi)仔的過程

26、的.那么攸入式系統(tǒng)中.動念分叱內(nèi)仔川能發(fā)生的 問題是什么?這也 我期望應(yīng)試打能捉到內(nèi)厶砰片砰片收集的汕一.變量的持行時間等等這個主題已經(jīng)4 ESP朵忑中被廣泛地討論過了要是PJ. Plauger, 他的解秫遠遠超過我這世能提到的任何解釋).所仃冋過頭看一下這些余忑吧! il應(yīng)試人進入種虛假的安門二 我京出這么一個小節(jié)弘下面的代碼片段的輸出是什么.為什么?char *ptr;if (ptr = (char *)malloc(O)=NULL)elseputs("Got a null pointer11);puts(MGot a valid pointer");這是一個有趣的問起

27、??谖业囊粋€同那不經(jīng)意把Offt傳給了函數(shù)malloc.得到了一個合法的拆針Z后.我才想到這個問題.這就是上而的代碼. 該代碼的輸出足-Got a valid pointer".我用這個來開始討論這樣的問題.看看枝血試咅足舎想到陽例程這樣做匕曲 得到正確的答案9B2 整.但解決問越的方法和你做決定的基木原理更取要蘭.Typedef15 Typedef diCitt繁川以聲明個C經(jīng)"在的數(shù)據(jù)類空的同義7。也町以川預處理器做類似的書。例如,思羽一卜'卜M的例厲#define dPS struct s *typedef struct s * tPS;以I:兩種情況的意

28、圖都是婆定義dPS和tPS作為一個折向結(jié)構(gòu)s拆針。哪種方法更好呢?(如果有的話)為什么?'個II常微妙的何題.仟何人衿對這個何題(正片的原因)是山 *4 typedefH卜Mi的例了:dPS pl,p2;tPS p3,p4;第一個擴展為struct s * pl, p2;Lhi的代碼定義pl為 個折向結(jié)構(gòu)的瓶p2為-個實際的結(jié)構(gòu),這也許不圧你想耍的。第二個例正確地定義了p3和p4兩個卅|呦澀的講法16 . C詢吉同應(yīng)些令人喪驚的結(jié)構(gòu),卜面的給構(gòu)是合法的嗎.如果是它做些什么?int a = 5r b = 7r c;c = a+b;這個何題將做為這個測驗的一個愉快的結(jié)毘.不管你相不相信.上面的例子是完全合乎講法的。問題是編譯器如何處理它?水平不扁的編譯作者實際 I:會爭論這個何題,根抿最處理原則.編譯器應(yīng)十能處理盡町能所右合法的用法。因此.卜Mi的代碼被處理成:c = a+ + b;因此.這段代碼持行打3 = 6r b = 7r c = 12.如果你知道答案.或磚H正確存案做得好如果你不知道存案,我也不把這個十作問題.我發(fā)現(xiàn)這個何題的昴大好處址這足一個關(guān)于代碼編卩風 恪.代碼的可讀性,代碼的可修改性的好的話題

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論