>
預處理器(preprocessor)
1. 用預處理指令#define 宣告乙個常數,用以表明1年中有多少秒(忽略閏年問題)
#define seconds_per_year (60 * 60 * 24 * 365)ul
我在這想看到幾件事情:
1). #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等)
2). 懂得預處理器將為你計算常數表示式的值,因此,直接寫出你是如何計算一年中
有多少秒而不是計算出實際的值,是更清晰而沒有代價的。
3). 意識到這個表示式將使乙個16位機的整型數溢位-因此要用到長整型符號l,告訴編
譯器這個常數是的長整型數。
4). 如果你在你的表示式中用到ul(表示無符號長整型),那麼你有了乙個好的起點。
記住,第一印象很重要。
2. 寫乙個「標準」巨集min,這個巨集輸入兩個引數並返回較小的乙個。
#define min(a,b) ((a) <= (b) (a) : (b)) 這個
測試硬體
暫存器(如:狀態暫存器)
2). 乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)
3). 多執行緒應用中被幾個任務共享的變數
回答不出這個問題的人是不會被僱傭的。我認為這是區分c程式設計師和嵌入式系統程式設計師的最
基本的問題。嵌入式系統程式設計師經常同硬體、中斷、rtos等等打交道,所用這些都要求vo
latile變數。不懂得volatile內容將會帶來災難。
假設被面試者正確地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看
一下這傢伙是不是直正懂得volatile完全的重要性。
1). 乙個引數既可以是const還可以是volatile嗎?解釋為什麼。
2). 乙個指標可以是volatile 嗎?解釋為什麼。
3). 下面的函式有什麼錯誤:
int square(volatile int *ptr)
下面是答案:
1). 是的。乙個例子是唯讀的狀態暫存器。它是volatile因為它可能被意想不到地改變。
它是const因為程式不應該試圖去修改它。
2). 是的。儘管這並不很常見。乙個例子是當乙個中服務子程式修該乙個指向乙個buffer
的指標時。
3). 這段**的有個惡作劇。這段**的目的是用來返指標*ptr指向值的平方,但是,由
於*ptr指向乙個volatile型引數,編譯器將產生類似下面的**:
int square(volatile int *ptr)
由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不
是你所期望的平方值!正確的**如下:
long square(volatile int *ptr)
位操作(bit manipulation)
9. 嵌入式系統總是要使用者對變數或暫存器進行位操作。給定乙個整型變數a,寫兩段**
,第乙個設定a的bit 3,第二個清除a 的bit 3。在以上兩個操作中,要保持其它位不變。
對這個問題有三種基本的反應
1). 不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。
2). 用bit fields。bit fields是被扔到c語言死角的東西,它保證你的**在不同編譯器
之間是不可移植的,同時也保證了的你的**是不可重用的。我最近不幸看到infineon為
其較複雜的
通訊品味
娛樂 吧…
動態記憶體分配(dynamic memory allocation)
14. 儘管不像非嵌入式計算機那麼常見,嵌入式系統還是有從堆(heap)中動態分配記憶體
的過程的。那麼嵌入式系統中,動態分配記憶體可能發生的問題是什麼?
這裡,我期望應試者能提到記憶體碎片,碎片收集的問題,變數的持行時間等等。這個主題
已經在esp雜誌中被廣泛地討論過了(主要是 p.j. plauger, 他的解釋遠遠超過我這裡能
提到的任何解釋),所有回過頭看一下這些雜誌吧!讓應試者進入一種虛假的安全感覺後
,我拿出這麼乙個小節目:下面的**片段的輸出是什麼,為什麼?
char *ptr;
if ((ptr = (char *)malloc(0)) == null)
puts("got a null pointer");
else
puts("got a valid pointer");
這是乙個有趣的問題。最近在我的乙個同事不經意把0值傳給了函式malloc,得到了乙個合
法的指標之後,我才想到這個問題。這就是上面的**,該**的輸出是「got a valid
pointer」。我用這個來開始討論這樣的一問題,看看被面試者是否想到庫例程這樣做是正
確。得到正確的答案固然重要,但解決問題的方法和你做決定的基本原理更重要些。
typedef
15. typedef 在c語言中頻繁用以宣告乙個已經存在的資料型別的同義字。也可以用預處理
器做類似的事。例如,思考一下下面的例子:
#define dps struct s *
typedef struct s * tps;
以上兩種情況的意圖都是要定義dps 和 tps 作為乙個指向結構s指標。哪種方法更好呢?
(如果有的話)為什麼?
這是乙個非常微妙的問題,任何人答對這個問題(正當的原因)是應當被恭喜的。答案是
:typedef更好。思考下面的例子:
dps p1,p2;
tps p3,p4;
第乙個擴充套件為
struct s * p1, p2;
上面的**定義p1為乙個指向結構的指,p2為乙個實際的結構,這也許不是你想要的。第
二個例子正確地定義了p3 和p4 兩個指標。
晦澀的語法
16. c語言同意一些令人震驚的結構,下面的結構是合法的嗎,如果是它做些什麼?
int a = 5, b = 7, c;
c = a+++b;
這個問題將做為這個測驗的乙個愉快的結尾。不管你相不相信,上面的例子是完全合乎語
法的。問題是編譯器如何處理它?水平不高的編譯作者實際上會爭論這個問題,根據最處
理原則,編譯器應當能處理盡可能所有合法的用法。因此,上面的**被處理成:
c = a++ + b;
因此, 這段**持行後a = 6, b = 7, c = 12。
如果你知道答案,或猜出正確答案,做得好。如果你不知道答案,我也不把這個當作問題
。我發現這個問題的最大好處是:這是乙個關於**編寫風格,**的可讀性,**的可修
改性的好的話題
嵌入式面試題
15 typedef 在c語言中頻繁用以宣告乙個已經存在的資料型別的同義字。也可以用預處理器做類似的事。例如,思考一下下面的例子 define dps struct s typedef struct s tps 以上兩種情況的意圖都是要定義dps 和 tps 作為乙個指向結構s指標。哪種方法更好呢?...
嵌入式面試題
1.main int ptr int a 1 printf d d a 1 ptr 1 這段程式的輸出是 a 2 2 b 2 1 c 2 5 d 以上均不是 2.考查自加操作 main 這段程式的輸出是 a i 4 j 2 b i 3 j 2 c i 3 j 4 d i 3 j 6 3.此題考查的是...
嵌入式面試題
以下是我找嵌入式面試時遇到的一些問題,答案以後慢慢補充。1.incline和巨集定義的區別 3.linux自旋鎖 4.程序,執行緒的概念 5.strcpy的使用,具體實現 6.雙向鍊錶的插入,刪除 7.大端小端概念 8.寫一段c程式檢測cpu是32位還是64位 9.malloc和new的使用 10....