面試C++試題 (轉)

amyz發表於2007-11-12
面試C++試題 (轉)[@more@] 

面試C++拾題:namespace prefix = o ns = "urn:schemas--com::office" />

前些天,我面試了幾個做C++的,這些天,也被人面試。

關於C++的面試方面,林銳博土的<<高質量C++/C指南>>裡附帶的一些試題被大量引證來測試應試人員的基礎。很不幸,我也被做了一份,回來後,和林銳的標準答案一對,覺得,他的答案還是有些不足之處,下面我就說說那兩個題,也許憑記憶能回憶起面試中的一些趣事。

1.已知strcpy的原型是

  char *strcpy(char *strDest, const char *strSrc);

  其中strDest是目的字串,strSrc是源字串。

不C++/C的字串庫函式,請編寫函式 strcpy

林銳的標準答案如下:

char *strcpy(char *strDest, const char *strSrc);

{

   assert((strDest!=NULL) && (strSrc !=NULL));  // 2分

   char *address = strDest;      // 2分

   while( (*strDest++ = * strSrc++) != )    // 2分

   NULL ;

   return address ;        // 2分

}

我在寫時,寫出下面這樣子的:

char *strcpy_x(char *strDest, const char *strSrc)

{

  if((strDest==NULL) || (strSrc ==NULL))

  return NULL;  // 2分

   if(strDest==strSrc)//add by xie

  return strDest;  

  char *address = strDest;      // 2分

  while( (*strDest++ = * strSrc++) != ' )  // 2分

  ;

  return address ;      // 2分

}

我當時這樣寫的理由如下:

a.  沒必要為一個strcpy函式中的引數有NULL就斷言大錯湧出,返回NULL值也是一個好見識

b.  為了防止寫出strcpy(strDest,strSrc)(而strDest是等於strSrc,又很不湊巧strDest是大字串,這些程式碼又執行一種比較計時的環境下,所以判斷是否相同應該是必須的。更重要的一點:林銳的這篇文章影響了好多公司招人,這樣一寫,我給別人留下的印象是不同的,你認為呢?:)

 

2. 相信大部人都看過甚至做過下面這個題:

已知類String的原型為:

  class String

  {

    public:

    String(const char *str = NULL);  // 普通建構函式

    String(const String &other);    // 複製建構函式

  ~ String(void);        // 解構函式

    String & operate =(const String &other);  // 賦值函式

    private:

  char    *m_data;      // 用於儲存字串

  };

  請編寫String的上述4個函式。

在我給出我找碴的理由先,我先給出林銳的標準答案及指出一點不足處:

// String的解構函式

  String::~String(void)  // 3分

{

  delete [] m_data;   

// 由於m_data是內部資料型別,也可以寫成 delete m_data;

  }

 

  // String的普通建構函式 

  String::String(const char *str)  // 6分

{

  if(str==NULL) 

  {

    m_data = new char[1];  // 若能加 NULL 判斷則更好

    *m_data = ;   

  }   

  else

  {

    int length = strlen(str); 

    m_data = new char[length+1];  // 若能加 NULL 判斷則更好 

    strcpy(m_data, str); 

  }

// 複製建構函式

  String::String(const String &other)  // 3分

  { 

  int length = strlen(other.m_data); 

  m_data = new char[length+1];  // 若能加 NULL 判斷則更好 

  strcpy(m_data, other.m_data); 

}

// 賦值函式

  String & String::operate =(const String &other)  // 13分

  { 

  // (1) 檢查自賦值  // 4分

    if(this == &other)

    return *this;

 

// (2) 釋放原有的資源  // 3分

    delete [] m_data;

 

  // (3)分配新的記憶體資源,並複製內容 // 3分

  int length = strlen(other.m_data); 

  m_data = new char[length+1];  // 若能加 NULL 判斷則更好

    strcpy(m_data, other.m_data);

 

  // (4)返回本的引用  // 3分

    return *this;

我記得我去年初買了<>時,裡面也以String為例作了一個介紹,不過書到用時找不到,因為我已送給好學後進了。而電子版的,我當時在網上看了,但好像沒當下來。我依稀記得裡面的複製建構函式也要判斷if(this == &other)的,不過我認為要是已實現了operator==函式的話,if(*this == other)會更好一些,因為例如象String的兩個物件,內容一樣,一個給另一個賦值時,用if(*this == other)的判斷的話,就可避免下一些操作了。黑夜給了我黑色的眼,我睜一隻眼閉一隻眼都可以看出上面的標準答案裡關於複製建構函式中沒有這樣的判斷,對了,上文中的operator被誤寫成operate了,那些公司裡的試題也是這樣子的,讓我看的時候愣了下。

大家可能會認為複製建構函式是建構函式,怎麼會傳進去它自己呢?肯定是別的物件了。很搞笑的是:String ss(ss),沒錯,String ss(ss=”xieyingjun”)也是對的寫法(對了,我沒就這個C++語意檢視C++標準,要是根據C++98的標準,我的說法扯淡,也請付之一笑)。文後我附上本篇文章的測試程式碼。您也可以在C++Builder中先打上這兩行,看看結果:AnsiString ss(ss=”xieyingjun”);ShowMessage(ss); 不過,很不幸,類似的程式碼用STL中的String或VC中的CString來實現,執行結果好象並非是一帆風順。

 

#include

char *strcpy_x(char *strDest, const char *strSrc)

{

  if((strDest==NULL) || (strSrc ==NULL))

  return NULL;  // 2分

  if(strDest==strSrc)//add by xie

  return strDest; 

  char *address = strDest;      // 2分

  while( (*strDest++ = * strSrc++) != ' )  // 2分

  ;

  return address ;      // 2分

}

 

 

class String

  {

    friend std::ostream& operator <

    public:

    String(const char *str = NULL);  // 普通建構函式

    String(const String &other);    // 複製建構函式

  ~ String(void);         // 解構函式

    String & operator =(const String &other); // 賦值函式

    private:

    char    *m_data;    // 用於儲存字串

  };

 

// String的解構函式

String::~String(void)  // 3分

{

  delete [] m_data;

  m_data=0; //add by xie   

// 由於m_data是內部資料型別,也可以寫成 delete m_data;

//note by xie:有次去華為,華為批題,寫成delete m_data;不給分,一個人的見識就是這樣得來的,:P 

}

 

  // String的普通建構函式 

String::String(const char *str)  // 6分

{

  if(str==NULL) 

  {

    m_data = new char[1];  // 若能加 NULL 判斷則更好

    *m_data = '; 

  }   

  else

  {

    int length = strlen(str); 

    m_data = new char[length+1];  // 若能加 NULL 判斷則更好 

    strcpy(m_data, str); 

  }

// 複製建構函式

  String::String(const String &other)  // 3分

  { 

   if(this==&other)

    return; //add by xie

  int length = strlen(other.m_data); 

  m_data = new char[length+1];  // 若能加 NULL 判斷則更好 

  strcpy(m_data, other.m_data); 

}

// 賦值函式

  String & String::operator =(const String &other)  // 13分

  { 

  // (1) 檢查自賦值  // 4分

    if(this == &other)

    return *this;

 

// (2) 釋放原有的記憶體資源  // 3分

    delete [] m_data;

 

  // (3)分配新的記憶體資源,並複製內容 // 3分

  int length = strlen(other.m_data); 

  m_data = new char[length+1];  // 若能加 NULL 判斷則更好

    strcpy(m_data, other.m_data);

 

  // (4)返回本物件的引用  // 3分

    return *this;

std::ostream& operator <

{

  os<

  return os; 

}

 

int main()

{

  const char s1[]="hello world!";

  char s2[100];

  char s3[100];

  strcpy_x(s3, strcpy_x(s2,s1));

 

  std::cout<

  std::cout<

 

  String ss(ss=s1);

  std::cout<

 /*此處會報一個記憶體不能read的錯,具體原因引起,還要看C++標準關於這處的語意定義,再作修改,不過要是有人寫出大量的不當類似實現程式碼也會造成記憶體洩露的。 */

  return 0;

}

 

3.無聊的人生是充滿智慧的人生。我突然無緣無故的想出這句很NB的話(不知是否原創啊:我不確定是否來自記憶或是一時漢詞重組)。願與很NB的各位共勉啊。

4.標題拾是撿起的意思,不是數字10的中文大寫。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-981915/,如需轉載,請註明出處,否則將追究法律責任。

相關文章