C語言學習趣事_經典面試題系列_3

來源:互聯網
上載者:User

         有日子沒有學習C語言了, 前些天在看windows程式設計時, 按照win的體繫結構,在VC 6裡面找到

下面一段代碼,發現自己的C語言功底實在是差之又差。代碼為我看到的C代碼,至目前為止,還只能理解個大概;

估計要慢慢體會了。

View Code

DECLARE_HANDLE(HDC);


#define DECLARE_HANDLE(name)
struct name##__
{
int unused;
};
typedef struct name##__ *name

      上面的代碼等我理解後再和大家分享吧, 下面說說這一次的C語言面試題。

 8、找錯題
 找出下面幾個函數的錯誤:
試題1:
  void test1()
       {
      char string[10];
      char* str1 = "0123456789";
      strcpy( string, str1 );
       }

/*
   這個題目咋一看,沒有任何錯誤, 給strcpy()函數傳遞的兩個實參參數類型均能滿足要求。
   但是細心一看我們會發現這個函數存在越界問題,"0123456789"這個字串
   的長度為 strlen("0123456789") + 1 = 11 , 而很顯然string[10],不可能儲存這麼大的空間
   通常在使用strcpy函數時一定要考慮源串、和目的串的大小問題。

*/
   函數改成下面的形式可能會健壯一些:
    int StrCpy(const char *source; char dest[])
     {
         if( NULL==source || NULL == dest || ( strlen(dest) < strlen(source) ) )
              return 1;   // 傳回值=1 表示複製失敗
         else
             strcpy(dest,source);           
         return 0;   //傳回值=0 表示複製成功
     }
 

試題2::
void test2()
{
   char string[10], str1[10];
   int i;
   for(i=0; i<10; i++)
     {
        str1 = 'a';
      }
 strcpy( string, str1 );
}
/*
這個題目考查了兩個問題: 
    1、 數組的首地址是常量,不可以作為左值, 即str1是一個常量,
        它代表整個數組的首地址。
    2、 第二數組的引用需要用下標,除了初始化時可以int iArray[10]={1,2}
        這樣賦值外,在其他地方不可以批量給數組元素賦值。
    3、 同時strcpy複製函數是針對具有'\0'的字元類型變數,因此這個函數賦
        值同樣存在賦值越界的情況。
*/
改成下面的方式估計會健壯一些:
void  test2( )
{
   char string[10],
         str1[10] ;
   for(int i=0; i<10; i++)
      str1[i] = 'a';
       str[9]='\0';
   strcpy(string , str1);
}

試題3:
void test3(char* str1)
  {
    char string[10];
    if( strlen( str1 ) <= 10 )
      {
        strcpy( string, str1 );
       }
   }
 //試題3同樣存在越界的可能性。如果strlen(str1)=10, 則實際上str1佔用的空間是11個。
 //strlen函數返回的長度沒有計算末尾'\0'字元。 因此需要注意。
改為下面的方式可能會更健壯:
void  test3(char* str1)
  {
    char string[10];
    if( strlen( str1 ) < 10 && NULL != str1 )
        strcpy( string, str1 );
   }

試題4:
 void GetMemory( char *p )
   {
     p = (char *) malloc( 100 );
   }

 void Test( void )
  {
   char *str = NULL;
   GetMemory( str );
   strcpy( str, "hello world" );
   printf( str );
  }
/*
首先這個題目存在記憶體泄露的問題和指標指向空地址問題
說說這個題目的存在的幾個問題:
 1、 在GetMemory函數裡面, 沒有對malloc函數傳回值進行測試
     if(NULL==p)
 2、 在函數裡面沒有對指標p進行釋放
     free(p);
 3、這裡會有一個問題,在C語言中預設時按值傳遞的, 不是按照地址傳遞的。
    在程式裡面不能改變str的指向。
      GetMemory(str);不能改變str的指向。 
    函數原型為:
       void GetMemory(char *p); 定義的就是一個指標類型的參數。
  4、在函數內部不能改變傳值參數的值
*/

/*****************
malloc函數的實質體現在,它有一個將可用的記憶體塊串連為一個長長的列表的所謂空閑鏈表。調用malloc函數時,
它沿串連表尋找一個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求
的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果
有的話)返回到串連表上。調用free函數時,它將使用者釋放的記憶體塊串連到空閑鏈上。到最後,空閑鏈會被切成很多
的小記憶體片段,如果這時使用者申請一個大的記憶體片段,那麼空閑鏈上可能沒有可以滿足使用者要求的片段了。於是,
malloc函數請求延時,並開始在空閑鏈上翻箱倒櫃地檢查各記憶體片段,對它們進行整理,將相鄰的小空閑塊合并成較大
的記憶體塊。如果無法獲得符合要求的記憶體塊,malloc函數會返回NULL指標,因此在調用malloc動態申請記憶體塊時,一定要
進行傳回值的判斷。
**************/

改成下面形式可能更健壯一些:
  Void GetMemory(char **p)
   {     
         char *temp;
         if(NULL != (temp=(char *)malloc(1000)))
               *p=temp;
         free(temp);
   }
                        

試題5:
char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}

void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}

/* 其實怎麼說呢這個題目的理解比上面一個題目來對簡單, 但是通過這個題目和上面
的題目需要知道一個事實:
    那就是函數內部聲明的局部變數(static類型的除外,當然還有register的除外),這裡指的
    是auto類型的變數, 其記憶體空間是在系統為應用程式開闢的棧裡面申請。
    而malloc函數申請的空間則是從系統為應用程式開闢的堆裡面申請。堆裡面申請的不會自動釋放,
    而棧裡面申請的會隨著函式宣告周期的結束而自動釋放。 
這個題目的錯誤之處在於沒有理解局部變數的生命週期。
*/
改成下面的形式可能會更健壯:
char *getmemory(void)
{
    char *p=NULL;
    if(NULL !=(p=(char *)malloc(strlen("hello word")+1))
       return p;
}

/*

 但是這樣返回的的指標是游離的, 沒有任何意義

*/
 

試題6:

void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}
/*
   這個題目在第四個題目已經實現和論述,不再論述
 指的一提的是:
     傳遞&str值,並不能改變str的指向。
*/

試題7:

void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它語句
}
/*
   這個題目比上面的更加簡單, 它的問題就是沒有對malloc函數的返回情況進行
   檢測,
   如果 NULL=(char *)malloc(NUM) 那麼strcpy函數將不會成功執行,
  
*/

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.