嵌入式軟體經典面試題

2021-10-06 08:31:48 字數 3977 閱讀 6634

用預處理命令#define宣告乙個常數,用以表明一年中有多少秒(忽略閏年問題)

#define year (60*60*24*365)ul
考點

1)#define語法的基礎知識

2)懂得預處理器將為你計算常數表示式的值,因此,直接寫出你是何年機斷一年中有多少秒而不是計算出實際的值,是更清晰沒有代價的。

3)意識到這個表示式將使用乙個16位機的整型數溢位,因此要使用到成整形符號l,告訴編譯器這是長整型數值。

4)如果在你使用表示式中用到ul(無符號長整形),表明有乙個良好的編譯習慣

#define 的作用

在c或c++語言源程式中允許用乙個識別符號來表示乙個字串,稱為「巨集」。被定義為「巨集」的識別符號稱為「巨集名」。在編譯預處理時,對程式中所有出現的「巨集名」,都用巨集定義中的字串去代換,這稱為「巨集代換」或「巨集展開」。巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。「巨集」分為有引數和無引數兩種。還可以防止重複定義。

#difine m (a)+(b)

m*m=

(a)+

(b)*

(a)+

(b)

上例提醒我們,需要在括號的使用上,一定注意

對於巨集定義還要注意:

1. 預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。

2. 巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。

3. 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用#undef命令。

這個巨集輸入兩個引數並返回乙個較小的乙個

#define min(a,b)    ((a)>=(b)?(b):(a))
1)懂得在巨集中小心的把引數用括號括起來。

2)指標越界可能是很嚴重的問題

3)了解巨集的***

例子:

least=min(*p++

,b)

有興趣的可以自行實踐

當預處理器預處理到#error命令時將停止編譯並輸出使用者自定義的錯誤訊息

用法示例:

檢查編譯此原始檔的編譯器是不是c++編譯器

如果使用的是c語言編譯器則執行#error命令

如果使用的是 c++ 編譯器則跳過#error命令

while(1)

for(;

;)

goto

loop

1與2的比較:

for(;;)死迴圈裡的兩個;;代表兩個空語句,編譯器一般會優化掉它們,直接進入迴圈體。 while(1)死迴圈裡的1被看成表示式,每迴圈一次都要判斷常量1是不是等於零。相對來說for式死迴圈更加高效一點 當然以上條件成立還要看編譯器的優化,一些編譯器優化的兩者並無區別,但是,並非所有的編譯器都做了這樣的優化。

執行到"goto**"的時候,程式會自動跳到goto後面跟著的字元標誌處,即"loop"處…但是"loop"處位於"goto"**之前,因此跳到了"loop"的**處向下走,會又一次碰到goto…如此迴圈反覆,因此會變為死迴圈

用變數a給出下面定義

1)乙個整型數

2)乙個指向整型資料的指標

3)乙個指向指標的指標,他指向的指標是指向乙個整形數

4)乙個有5個整型數的陣列

5)乙個有5個指標的陣列,該指標是指向乙個整型數

6)乙個指向有5個整形數陣列的指標

7)乙個指向函式的指標,該函式有乙個整形引數並返回乙個整型數

8)乙個有5個指標的陣列,該指標指向乙個函式,該函式有乙個象形引數並返回乙個整型數

1)

int a;
int

*a;

int

**a;

int a[5]

;

int

*a[5

];

int

(*a)[5

];

7)

int (*a)

(int

)

int

(*a[5]

)(int)

三個作用

1)在函式體內,被定義的變數是static的變數,在其他函式呼叫該函式的過程中,維持其值不變

2)在模組內,在函式體外,被定義位static的變數,可以被該模組內的所有函式訪問,他是乙個本地的全域性變數。

3)在模組內,乙個被宣告位static的變數被限制在不能在模組外的函式呼叫。

上面三個知識點在其他的部落格中有詳細說明,在這裡還要提供一下其他操作:

使用define來進行位操作的定義:

#define bit(x) (0x01<<(x))

我們可以使用這個bit(x)來進行置位和清零:

置位

uint8_t a=

0x11;a|

=bit(3

);

清零

uint8_t a=

0x11;a&

=~bit(3)

;

int

*p;p=

0x5678

;*p=

0x1234

;

或者:

*(int

*const)(

0x5678)=

0x1234

;

1)中斷函式中不能有引數

2)中斷函式中不能有返回值

3)中斷中應該盡量簡單,不要進行浮點運算,不同的編譯器效果不同,浮點一般都是不可重入的,列印函式printf()經常有重入和效能上的問題。

unsigned

int a=6;

signed

int b=-20

;(a+b)

>6?

puts

(">6"):

puts

("<=6"

);

答案是前者!

當表示式中存在有符號和無符號型別時,所有的運算元都自動轉換為無符號的。因此-20變成了乙個非常大的數。

unsigned

int zero=0;

unsigned

int compzero=

0xffff

;

對於不是16位的編譯器,第二個應該這樣:

unsigned

int compzero-~0

;

在堆中動態記憶體分配可能會存在記憶體碎片。

char

*p;if

((p=

(char*)

malloc(0

))==null

)puts

("null");

else

put(

"yes"

);

會輸出yes;

#define d struct s*

typedef

struct s * p

上面兩種typedef更好,為什麼呢?

d d1,d2;

p p1,p2;

第一題擴充套件為:

struct s* d1,d2;
自然就可能會出現錯誤

嵌入式經典面試題

這些題實在太經典了 預處理器 preprocessor 1 用預處理指令 define 宣告乙個常數,用以表明1年中有多少秒 忽略閏年問題 define seconds per year 60 60 24 365 ul 我在這想看到幾件事情 1 define 語法的基本知識 例如 不能以分號結束,括...

嵌入式軟體開發經典面試題

在嵌入式軟體開發的面試中,遇到筆試的機率非常大。一般來說,筆試的題目不會太難,但牽涉的知識面比較廣。若你年底有找工作的計畫,有必要找一些筆試題看看,這樣能讓你從題目中掌握並學到很多知識。1.用 define 宣告乙個常數,表明 1年中有多少秒 忽略閏年問題 答案 define seconds per...

嵌入式軟體面試題一

1 請寫出你所知道的c 語言關鍵字。auto 宣告自動變數 switch 用於開關語句 case 開關語句分支 break 跳出當前迴圈 default 開關語句中的 其它 分支 goto 無條件跳轉語句 do 迴圈語句的迴圈體 while 迴圈語句的迴圈條件 if 條件語句 else 條件語句否定...