16道嵌入式 語言面試題

2021-04-12 12:45:58 字數 3322 閱讀 2340

>

預處理器(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....