重解幾道華爲經典C語言面試題

重解幾道華爲經典C語言面試題 面試


         1、找錯 數組

    一、找錯 函數

  void test1()
{
    char string[10];
    char* str1="0123456789";
    strcpy(string, str1);
}
spa


 
    這裏string數組越界,由於字符串長度爲10,還有一個結束符‘\0’。因此總共有11個字符長度。string數組大小爲10,這裏越界了。

內存

    PS:使用strcpy函數的時候必定要注意前面目的數組的大小必定要大於後面字符串的大小,不然即是訪問越界。 ci

  void test2()
{
    char string[10], str1[10];
    for(i=0; i<10;i++)
    {
       str1[i] =’a’;
    }
    strcpy(string, str1);
}
字符串


 
    這裏有一個一眼就能看出的問題,那就是變量i沒有定義,這在代碼編譯階段編譯器能夠幫你發現,很容易搞定。然而不少問題是本身形成的漏洞,編譯器是幫不上什麼忙的。這裏最大的問題仍是str1沒有結束符,由於strcpy的第二個參數應該是一個字符串常量。該函數就是利用判斷第二個參數的結束符來獲得是否拷貝完畢。因此在for循環後面應加上str1p[9] = ‘\0’

get

    PS:字符數組和字符串的最明顯的區別就是字符串會被默認的加上結束符‘\0’ 編譯器

  void test3(char* str1)
{
    char string[10];
    if(strlen(str1)<=10)
    {
       strcpy(string, str1);
    }
}
string


 
    這裏的問題還是越界問題。strlen函數獲得字符串除結束符外的長度。若是這裏是<=10話,就很明顯越界了。

    小結:上面的三個找錯的函數,主要是考查對字符串和字符數組的概念的掌握以及對strcpy函數和strlen函數的理解。

    二、找錯

  DSN get_SRM_no()
{
  static int SRM_no;
  int I;
  for(I=0;I<MAX_SRM;I++)
    {
       SRM_no %= MAX_SRM;
       if(MY_SRM.state==IDLE)
       {
         break;
       }
    }
    if(I>=MAX_SRM)
       return (NULL_SRM);
    else
       return SRM_no;
}


 
    這裏for循環的判斷語句是後來我加上的,估計在網上流傳的時候被人給弄丟了,根據對程序的分析,給補上了。估計錯誤應該不是這兒。

    簡單的閱讀一下這個函數,能夠大概的能夠猜想出這個函數的功能是分配一個空閒的SRAM塊。方法:從上次分配的RAM塊後的RAM塊開始檢測SRAM每一個RAM塊,看是不是IDLE狀態,若是是IDLE則返回當前的RAM塊的號SRM_no.若是全部的RAM塊都不是IDLE狀態,則意味着沒法分配一個RAM給函數調用者,返回一個表示沒有RAM可分配的標誌(NULL_SRM)。

    通過上面的分析,則這裏能夠知道,這個函數的錯誤是for循環裏面沒有給SRM_no這個變量累加1.

    三、寫出程序運行結果

  int sum(int a)
{
    auto int c=0;
    static int b=3;
    c+=1;
    b+=2;
    return(a+b+c);
}
void main()
{
    int I;
    int a=2;
    for(I=0;I<5;I++)
    {
       printf("%d,", sum(a));
    }
}


    運行結果是:810121416

    在求和函數sum裏面cauto變量,根據auto變量特性知每次調用sum函數時變量c都會自動賦值爲0.bstatic變量,根據static變量特性知每次調用sum函數時變量b都會使用上次調用sum函數時b保存的值。

    簡單的分析一下函數,能夠知道,若傳入的參數不變,則每次調用sum函數返回的結果,都比上次多2.因此答案是:810121416

  4func(1) = ?
int func(int a)
{
    int b;
    switch(a)
    {
        case 1: 30;
        case 2: 20;
        case 3: 16;
        default: 0;
    }
    return b;
}


    在 case 語句中可能忘記了對變量b賦值。若是改成下面的代碼:

  int func(int a)
{
    int b;
    switch(a)
    {
        case 1:      b = 30;
        case 2:      b = 20;
        case 3:      b = 16;
        default:     b = 0;
    }
    return b;
}


 
    由於case語句中漏掉了break語句,因此不管傳給函數的參數是多少,運行結果均爲0.

    五、a[q - p] = ?

   int a[3]

    a[0]=0 a[1]=1 a[2]=2

    int *p *q

    p=a

    q=&a[2]

    很明顯:a[q - p] = a[2] = 2


    六、內存空間佔用問題

    定義 int **a[3][4], 則變量佔有的內存空間爲:16位系統2432位編譯系統中是48.

    PS:公式:3 * 4 * sizeofint ** .

    七、程序編寫

    編寫一個函數,要求輸入年月日時分秒,輸出該年月日時分秒的下一秒。如輸入20041231235959秒,則輸出200511000秒。

void ResetTheTime(int *year,int *month,int *date,int *hour,int *minute,int*second)
{
    int dayOfMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};

    if( *year < 0   || *month < 1 || *month > 12 ||        *date < 1   || *date > 31 || *hour < 0   || *hour > 23 ||        *minute < 0 ||*minute > 59|| *second <0 || *second >60 )        return;     if( *year%400 == 0 || *year%100 != 0 && *year%4 == 0 )        dayOfMonth[1] = 29;     if(*second >= 60)     {        *second = 0;        *minute += 1;        if(*minute >= 60)        {            *minute = 0;            *hour += 1;            if(*hour >= 24)            {               *hour = 0;               *date += 1;               if(*date > dayOfMonth[*month-1])               {                   *date = 1;                   *month += 1;                   if(*month > 12)                   {                      *month=1;                       *year += 1;                   }               }            }        }     }     return; }

相關文章
相關標籤/搜索