1. 程式人生 > >嵌入式面試題整理(一)

嵌入式面試題整理(一)

自己整理了一些來自各個公司嵌入式行業的面試的題目。答案在後面(是自己寫的答案,不敢保證100%正確,哈哈,能力有限)。題目都是近兩年的公司面試題

  1. 關鍵字volatile有什麼含義?並列舉一個例子。
  2. 嵌入式系統總是要使用者變數或暫存器進行位操作。給定一個整變數a,寫兩段程式碼,第一個設定a的bit 3,第二個清零a的bit3。在以上兩個操作中,要保持其它位不變。
  3. 嵌入式系統經常具有要求程式設計師去訪問某特定的記憶體位置的特點。在某工程中,要求設定一絕對地址位0x67a9整型變數的值為0xaa66。編譯器是一個純粹的ANSI編譯器。寫程式碼去完成這一任務。
  4. 中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提供一種擴充套件—讓標準C支援中斷。 具代表事實是,產生一個新的關鍵字__interrupt。下面的程式碼就使用了__interrupt關鍵字去定義了一箇中斷服務子程式(ISR),請評論一下這段程式碼的。

__interrupt double compute _area(double radius)

{

double area = PI*radius *radius;

printf(” Area = %f”, area);

return area;

}

  1. 請問執行test函式會有什麼結果?為什麼?

(1)void getmemory( char *p )

{

P=(char*)malloc( 100 );

}

void test( void )

{

Char *str = null;

getmemory(str);

strcpy( str, “hello world” );

Printf( str );

}

(2)char *getmemory( void )

{

char p[] = “hello world”;

return p;

}

void test( void)

{

char *str = null;

str = getmemory();

printf( str );

}

6、用一句語句實現x是否是2的若干次冪的判斷?

解答:

Volatile關鍵字修飾變數,表示該變數是一個會意想不到改變的量(在某個特定的時刻就會改變),所以該變數是不能被編譯器優化的(有時編譯器為了操作方便,會把變數儲存在一個暫存器中,使用的時候會直接從暫存器去取該變數的值),要去讀取資料的時候要從儲存變數的記憶體單元去取。避免讀到的資料是有誤的。

例子:在使用多執行緒程式設計時,同時訪問同一個變數就可能造成資料不符的情況

小知識:C語言的原子性:在執行程式的過程中,如果一條語句不能被拆分,則該語句具有原子性。但在C語言中大部分語句是不具備原子性的。比如接下來的一條語句:i++; 剛剛接觸的可能會想,不就是i自加1嗎,這中間還會有其他的操作。答案是,會的,在彙編的時候該語句,包含了三個動作:1.讀取i變數到暫存器,2.暫存器的值加1,3.把結果儲存到i變數所對應的記憶體中。所以當多段程式碼同時要使用i變數的時候就會造成資料的錯誤讀寫。

2.

在做這道前要知道以下的知識點

1&0=0; 1&1=1; 0&0=0;

1|0=1; 1|1=1; 0|0=0;

1^0=1 1^1=0; 0^0=1;

瞭解這些這道題就比較簡單了;

將a的第三位置1,其他位不變 將a的第三位清0,其他位不變

a=a|(0x1<<2); a=a&(~(0x1<<2))

總結:(假設m=4)

一個整數n,把它的第m個二進位制位變成0,其他的二進位制位不允許改變

                    n = n&11111111 11111111 11111111 11110111

                    n = n&(~(1<<(m-1)))

一個整數n,把它的第m個二進位制位變成1,其他的二進位制位不允許改變

                    n = n|00000000 00000000 00000000 00001000

                    n = n|(1<<(m-1))

一個整數n,把它的第m個二進位制位反轉(原本1--》0原本0--》1),其他的二進位制位不允許改變

                    n = n^00000000 00000000 00000000 00001000

                    n = n^(1<<(m-1)

3.

   置一絕對地址位0x67a9整型變數的值為0xaa66。編譯器是一個純粹的ANSI編譯器。

方法一:

int *p;

p = (int *)0x67a9;

*p =(int) 0xaa55;

通過該方式可以比較明確的完成目標。

方法二:

一些大神也會這樣寫:

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

其實意思一樣的。

注:在你用unix來測試該端程式碼的時候會發生當段錯誤,可能在開發板上才能用(來沒有開始接觸開發板)。

4.

還沒有接觸到底層開發。。。........

5.

(1)void getmemory( char *p )

{

P=(char*)malloc( 100 );

}

void test( void )

{

char *str = null;

getmemory(str);

strcpy( str, “hello world” );

Printf( str );

}

首先要明白的一點是,char *p 這是str的形參,而不是儲存的str指標的地址,所以p和str是兩個,p的一切行為和str沒有任何關係。

所以在主函式執行完getmemory(str);後str還是一個指向NULL的一個指標。沒有被分配空間。所以執行strcpy( str, “hello world” );會發生錯誤

(2)char *getmemory( void )

{

char p[] = “hello world”;

return p;

}

void test( void)

{

char *str = null;

str = getmemory();

printf( str );

}

這個問題就比較明顯了,p是一個數組,是存放在是一個區域性變數,儲存在棧空間中,當getmemory()函式呼叫完後p的記憶體空間會被釋放掉,str得到的將會是一個野指標。自然不能列印想要的字串了。

6.

用一句語句實現x是否是2的若干次冪的判斷?

首先要了解的是如果一個數是2的若干次冪,那麼按照位來看,就是隻有滿足有且只有一位是1,其他全0;所以只要通過以下語句就可以實現了。

(x&(x-1))?(false):(ture)