程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言學習趣事_經典面試題系列_3

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

編輯:關於C語言

 有日子沒有學習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函數將不會成功執行,
  
*/

鑒於本人是個計算機菜鳥, 目前連基本的兼容dos命令都不會, 同時還是個C語言的菜鳥

上面的類容說的不當的地方,歡迎各位彎腰找板磚......................

嘻嘻..............................

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved