嵌入式軟件工程師面試(2)

1、

int main(void)
{
   unsigned int a = 6;
   int b = -20;
   char c;
   (a+b>6)?(c=1):(c=0);
}

則c=1,但a+b=-14;如果a爲int類型則c=0。

原來有符號數和無符號數進行比較運算時(==,<,>,<=,>=),有符號數隱式轉換成了無符號數(即底層的補碼不變,但是此數從有符號數變成了無符號數),比如上面 (a+b)>6這個比較運算,a+b=-14,-14的補碼爲1111111111110010。此數進行比較運算時,
 被當成了無符號數,它遠遠大於6,所以得到上述結果。


2、給定一個整型變量a,寫兩段代碼,第一個設置a的bit3,第二個清除a的bit,在以上兩個操作中, 要保持其它位不變。

#define BIT3 (0x1<<3)

static int a;
void set_bit3(void)
{
  a |= BIT3;
}

void clear_bit3(void)
{
   a &= ~BIT3;
}

3、要求設置一絕對地址爲0x67a9的整型變量的值爲0xaa66。

unsigned int *ptr;
ptr = (unsigned int *)0x67a9;
*ptr = 0xaa66;

4、中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提供一種擴展—讓標準C支持中斷。 具代表性的是,產生了一個新的關鍵字__interrupt。下面的代碼就使用了__interrupt關鍵字去定義了一箇中斷服務子程序(ISR),請評論一下這段代。

__interrupt void compute_area (void) 
 { 
   double area = PI * radius * radius; 
   printf(" Area = %f", area); 
   return area; 
 } 
  • ISR不可能有參數和返回值的!
  •  ISR儘量不要使用浮點數處理程序,浮點數的處理程序一般來說是不可重入的,而且是消耗大量CPU時間的!!
  •  printf函數一般也是不可重入的,UART屬於低速設備,printf函數同樣面臨大量消耗CPU時間的問題!

5、評價下面的代碼片斷:

unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */

對於一個int型不是16位的處理器爲說,上面的代碼是不正確的。應編寫如下:

unsigned int compzero = ~0;

6、解析下面代碼

main()
{
    char *ptr;
   if ((ptr = (char *)malloc(0)) == NULL)
       puts("Got a null pointer");
    else
       puts("Got a valid pointer");
}

 該代碼的輸出是“Got a valid pointer”。

將代碼改爲:

char *ptr;
if(int pp = (strlen(ptr=(char *)malloc(0))) == 0)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

或者:

char *ptr;
if(int pp = (sizeof(ptr=(char *)malloc(0))) == 4)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

如果求ptr的strlen的值和sizeof的值,該代碼的輸出是"Got a null pointer"。

注意:此時malloc(0)返回了一個可用於free()釋放的唯一指針(非NULL),而且將它傳給strlen(),返回值爲0,這樣看來,它用'\0'進行填充的(即內容是NULL而非指針指向NULL)。


7、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 兩個指針。
 


8、

int a = 5, b = 7, c;
c = a+++b;

c=12,由貪心法此式子可以解析成a++ + b,由於++在a的後面,先計算後再執行自加。


9、

int main()
{
   int j=2;
   int i=1;
   if(i = 1) j=3;
   if(i = 2) j=5;
   printf("%d",j);
} 

 輸出爲5,注意看清楚題目。


10、宏定義是在預編譯階段被處理的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章