首頁 >後端開發 >C#.Net教程 >7個華為關於C語言的經典面試題(分享)

7個華為關於C語言的經典面試題(分享)

青灯夜游
青灯夜游轉載
2020-08-03 17:30:503147瀏覽

7個華為關於C語言的經典面試題(分享)

1、找錯

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

       這裡string陣列越界,因為字串長度為10,還有一個結束符號'\0' 。所以總共有11個字元長度。 string數組大小為10,這裡越界了。

PS:使用strcpy函數的時候一定要注意前面目的數組的大小一定大於後面字串的大小,否則便是訪問越界。

void test2()
{
    char string[10], str1[10];
    for(i=0; i<10;i++)
    {
       str1[i] =&#39;a&#39;;
    }
    strcpy(string, str1);
}

    這裡有一個一眼就能看出的問題,那就是變數i沒有定義,這在程式碼編譯階段編譯器可以幫你發現,很容易搞定。然而很多問題是自己造成的漏洞,編譯器是幫不上什麼忙的。這裡最大的問題還是str1沒有結束符,因為strcpy的第二個參數應該是一個字串常數。函數就是利用判斷第二個參數的結束符號來得到是否拷貝完畢。所以在for循環後面應加上str1p[9] = '\0';

PS:字元陣列和字串的最明顯的差異就是字串會被預設的加上結束符號'\0 '。

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

       這裡的問題仍是越界問題。 strlen函數得到字串除結束符外的長度。如果這裡是<=10話,就很明顯越界了。

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

2、找錯

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。

3、寫出程式運行結果

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));
    }
}

運行結果是:8,10,12,14,16,

在求和函數sum裡面c是auto變量,根據auto變數特性知每次呼叫sum函數時變數c都會自動賦值為0。 b是static變量,根據static變數特性知每次呼叫sum函數時變數b都會使用上次呼叫sum函數時b保存的值。

簡單的分析一下函數,可以知道,若傳入的參數不變,則每次呼叫sum函數傳回的結果,都比上次多2。所以答案是:8,10,12,14,16,

4、func(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。

5、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 ;

6、記憶體空間佔用問題

定義 int **a[3][4], 則變數佔有的記憶體空間為:16位元系統24, 32位元編譯系統中是48。

PS:公式:3 * 4  * sizeof(int **) 。

7、程式編寫

寫函數,要求輸入年月日時分秒,輸出該年月日時分秒的下一秒。如輸入2004年12月31日23時59分59秒,則輸出2005年1月1日0分0秒。

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;
}

推薦:《c語言教學

以上是7個華為關於C語言的經典面試題(分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除