c++ 面試題

sunmenggmail發表於2012-04-26

轉自:http://blog.csdn.net/odola/article/details/4408136

char str1[]       = "abc";
char str2[]       = "abc";
const char str3[] = "abc"; 
const char str4[] = "abc"; 
const char* str5 = "abc";
const char* str6 = "abc";
cout << boolalpha << ( str1==str2 ) << endl; // 輸出什麼? false
Cout << boolalpha << ( str3==str4 ) << endl; // 輸出什麼? false
Cout << boolalpha << ( str5==str6 ) << endl; // 輸出什麼? true
答:
str1和str2都是字元陣列,每個都有其自己的儲存區,它們的值則是各儲存區首地址,不等;str3和 str4同上,只是按const語義,它們所指向的資料區不能修改。str5和str6並非陣列而是字元指標,並不分配儲存區,其後的“abc”以常量形式存於靜態資料區,而它們自己僅是指向該區首地址的指標,相等


2. 非C++內建型別 A 和 B,在哪幾種情況下B能隱式轉化為A?[C++中等]
答:
a. class B : public A { ……} // B公有繼承自A,可以是間接繼承的
b. class B { operator A( ); } // B實現了隱式轉化為A的轉化
c. class A { A( const B& ); } // A實現了non-explicit的引數為B(可以有其他帶預設值的引數)建構函式
d. A& operator= ( const A& ); // 賦值操作,雖不是正宗的隱式型別轉換,但也可以勉強算一個


3. 以下程式碼中的兩個sizeof用法有問題嗎?[C易]
void UpperCase( char str[]) // 將 str 中的小寫字母轉換成大寫字母
{
    for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++I )
        if( 'a'<=str[i] && str[i]<='z' )
            str[i] -= ('a'-'A' );
}
char str[] = "aBcDe"; //含有6個字元,最後一個為結束符
cout << "str字元長度為: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
答:
在呼叫UpperCase的函式時,實際傳入的是一個地址指標。在函式引數中,char str[]與char *效果是一樣的,這樣的話實際上uppercase中的sizeof(str)實際上是求指標佔了多少
個位元組,是4而不是字元的長度6.解決辦法:需要給UpperCase函式加一個引數,void UpperCase( char str[],int n);這個n是傳進來的陣列的長度。
void UpperCase( char str[],int n) // 將 str 中的小寫字母轉換成大寫字母
{
    for( size_t i=0; i<n; ++i )
        if( 'a'<=str[i] && str[i]<='z' )
            str[i] -= ('a'-'A' );
}

 

4. 以下程式碼有什麼問題?[C難]
void char2Hex( char c ) // 將字元以16進製表示
{
    char ch = c/0x10 + '0'; if( ch > '9' ) ch += ('A'-'9'-1);
    char cl = c%0x10 + '0'; if( cl > '9' ) cl += ('A'-'9'-1);
    cout << ch << cl << ' ';
}
char str[] = "I love 中國";
for( size_t i=0; i<strlen(str); ++i )
    char2Hex( str[i] );
cout << endl;
答:

只對ASCII字元有效,對漢字不適用,漢字已經超出256了。


4. 以下程式碼有什麼問題?[C++易]
struct Test
{
    Test( int ) {}
    Test() {}
    void fun() {}
};
void main( void )
{
    Test a(1);
    a.fun();
    Test b();
    b.fun();
}
答:Test b(); 應該直接寫Test b或者Test *b=new Test();


5. 以下程式碼有什麼問題?[C++易]
cout << (true?1:"1") << endl;
答:三元表示式“?:”問號後面的兩個運算元必須為同一型別。


6. 以下程式碼能夠編譯通過嗎,為什麼?[C++易]
unsigned int const size1 = 2;
char str1[ size1 ];
unsigned int temp = 0;
cin >> temp;
unsigned int const size2 = temp;
char str2[ size2 ];
答:不能。在編譯階段,由於temp=0。不能初始化一個char 陣列的長度為0。宣告陣列時指定元素數目,它必須是整型常數或const值,該const的值也必須在編譯時期確定,但是
在這裡size2的值在執行時才確定為temp的值。要求所有的值在編譯時是已知的!!陣列不能用變數作為長度進行宣告,因為變數的值是在執行時指定。


7. 以下程式碼中的輸出語句輸出0嗎,為什麼?[C++易]
struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i) {}
    CLS()
    {
        CLS(0);
    }
};
CLS obj;
cout << obj.m_i << endl;
答:不能。因為只是在CLS obj的時候,在建構函式CLS()中生成的臨時的CLS物件裡邊的m_i進行了賦值!


8. C++中的空類,預設產生哪些類成員函式?[C++易]
答:
class Empty
{
public:
    Empty();                                         // 預設建構函式
    Empty( const Empty& );                    // 拷貝建構函式
    ~Empty();                                       // 解構函式
    Empty& operator=( const Empty& );   // 賦值運算子
    Empty* operator&();                        // 取址運算子
    const Empty* operator&() const;       // 取址運算子 const
};

需要注意的是隻有當你需要用到這些函式的時候,編譯器才會去定義它們。


9. 以下兩條輸出語句分別輸出什麼?[C++難]
float a = 1.0f;
cout << (int)a << endl;
cout << (int&)a << endl;
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 輸出什麼?
Float b = 0.0f;
cout << (int)b << endl;
cout << (int&)b << endl;
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 輸出什麼?
:(1)(2)分別輸出false和true。注意轉換的應用。(int)a實際上是以浮點數a為引數構造了一個整型數,該整數的值是1,(int&)a則是告訴編譯器將a當作整數看(並沒有做任何
實質上的轉換)。因為1以整數形式存放和以浮點形式存放其記憶體資料是不一樣的,因此兩者不等。對b的兩種轉換意義同上,但是0的整數形式和浮點形式其記憶體資料是一樣的,因此在這種特殊情形下,兩者相等(僅僅在數值意義上)。
注意,程式的輸出會顯示(int&)a=1065353216,這個值是怎麼來的呢?前面已經說了,1以浮點數形式存放在記憶體中,按ieee754規定,其內容為0x0000803F(已考慮位元組反序)。
這也就是a這個變數所佔據的記憶體單元的值。當(int&)a出現時,它相當於告訴它的上下文:“把這塊地址當做整數看待!不要管它原來是什麼。”這樣,內容0x0000803F按整數解釋,其值正好就是1065353216(十進位制數)。
通過檢視彙編程式碼可以證實“(int)a相當於重新構造了一個值等於a的整型數”之說,而(int&)的作用則僅僅是表達了一個型別資訊,意義在於為cout<<及==選擇正確的過載版本。


10. 以下反向遍歷array陣列的方法有什麼錯誤?[STL易]
vector array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );

for( vector::size_type i=array.size()-1; i>=0; --I ) // 反向遍歷array陣列
{
    cout << array[i] << endl;
}

答:首先陣列定義有誤,應加上型別引數:vector<int> array。其次vector::size_type被定義為unsigned int,即無符號數,這樣做為迴圈變數的i為0時再減1就會變成最大的整數,導致迴圈失去控制。

 


11. 以下程式碼有什麼問題?[STL易]
typedef vector<int> IntArray;
IntArray array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 2 );
array.push_back( 4 );
// 刪除array陣列中所有的2
for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
{
    if( 2 == *itor ) array.erase( itor );
}
答:當刪除了第一個2之後,這個時候的iterator指向vector的第三個元素,此時的vector的元素為[1,2,4],這樣就跳過了第二個2,而直接檢查了4,所以沒有刪乾淨。正確方

法是:
for(Intarray::iterator itor=array.begin();itor!=array.end();++itor)
{
   if(2==*itor)
   {
       array.erase(itor);
       itor--; //在erase之後使迭代器回退一位
    }
}

for(Intarray::iterator it = array.begin();it!=array.end();)

{

if(*it == 2)

it = array.erase(it);

else

           ++it;

}


如果是set也一樣

set<int> s;

s.inert(3);

....


for(set<int>::iterator it = s.begin();it!=s.end();++it)

{

if(*it == 2)

            it = s.earae(it);

       else

           ++it;

}

12. 寫一個函式,完成記憶體之間的拷貝。[考慮問題是否全面]
答:
void* mymemcpy( void *dest, const void *src, size_t count )
{
    char* pdest = static_cast<char*>( dest );
    const char* psrc = static_cast<const char*>( src );
    if( pdest>psrc && pdest<psrc+cout ) 能考慮到這種情況就行了
    {
        for( size_t i=count-1; i!=-1; --I )
                pdest[i] = psrc[i];
    }
    else
    {
        for( size_t i=0; i<count; ++I )
            pdest[i] = psrc[i];
    }
    return dest;
}
int main( void )
{
    char str[] = "0123456789";
    mymemcpy( str+1, str+0, 9 );
    cout << str << endl;

    system( "Pause" );
    return 0;
}

相關文章