1. 程式人生 > >阿里面試必會20道C++面試題!

阿里面試必會20道C++面試題!

1、如何初始化一個指標陣列。
解析:首先明確一個概念,就是指向陣列的指標,和存放指標的陣列。 指向陣列的指標:char (*array)[5];含義是一個指向存放5個字元的陣列的指標。 存放指標的陣列:char *array[5];含義是一個數組中存放了5個指向字元型資料的指標。 按照題意,我理解為初始化一個存放指標的陣列,char *array[2]={“China”,”Beijing”};其含義是初始化了一個有兩個指向字元型資料的指標的陣列,這兩個指標分別指向字串”China”和”Beijing”。
2、關鍵字const是什麼含意?
解析:我只要一聽到被面試者說:“const意味著常數”,我就知道我正在和一個業餘者打交道。去年Dan Saks已經在他的文章裡完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應該非常熟悉const能做什麼和不能做什麼.如果你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可 以了。儘管這個答案不是完全的答案,但我接受它作為一個正確的答案。(如果你想知道更詳細的答案,仔細讀一下Saks的文章吧。)如果應試者能正確回答這 個問題,我將問他一個附加的問題:下面的宣告都是什麼意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前兩個的作用是一樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指標(也就是,整型數是不可修改的,但指標可以)。第四個意思a是一個指向整 型數的常指標(也就是說,指標指向的整型數是可以修改的,但指標是不可修改的)。最後一個意味著a是一個指向常整型數的常指標(也就是說,指標指向的整型 數是不可修改的,同時指標也是不可修改的)。如果應試者能正確回答這些問題,那麼他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關鍵字 const,也還是能很容易寫出功能正確的程式,那麼我為什麼還要如此看重關鍵字const呢?我也如下的幾下理由: 1). 關鍵字const的作用是為給讀你程式碼的人傳達非常有用的資訊,實際上,宣告一個引數為常量是為了告訴了使用者這個引數的應用目的。如果你曾花很多時間清理 其它人留下的垃圾,你就會很快學會感謝這點多餘的資訊。(當然,懂得用const的程式設計師很少會留下的垃圾讓別人來清理的。) 2). 通過給優化器一些附加的資訊,使用關鍵字const也許能產生更緊湊的程式碼。 3). 合理地使用關鍵字const可以使編譯器很自然地保護那些不希望被改變的引數,防止其被無意的程式碼修改。簡而言之,這樣可以減少bug的出現。
const關鍵字至少有下列n個作用:
(1)欲阻止一個變數被改變,可以使用const關鍵字。在定義該const變數時,通常需要對它進行初始化,因為以後就沒有機會再去改變它了;
(2)對指標來說,可以指定指標本身為const,也可以指定指標所指的資料為const,或二者同時指定為const;
(3)在一個函式宣告中,const可以修飾形參,表明它是一個輸入引數,在函式內部不能改變其值;
(4)對於類的成員函式,若指定其為const型別,則表明其是一個常函式,不能修改類的成員變數;
(5)對於類的成員函式,有時候必須指定其返回值為const型別,以使得其返回值不為“左值”。
例如:
const classA operator*(const classA& a1,const classA& a2); 
  operator*的返回結果必須是一個const物件。如果不是,這樣的變態程式碼也不會編譯出錯:
classA a, b, c;
(a * b) = c; // 對a*b的結果賦值 
  操作(a * b) = c顯然不符合程式設計者的初衷,也沒有任何意義。

3、 什麼是動態特性?
解析:在絕大多數情況下, 程式的功能是在編譯的時候就確定下來的, 我們稱之為靜態特性。 反之, 如果程式的功能是在執行時刻才能確定下來的, 則稱之為動態特性。C++中, 虛擬函式,抽象基類, 動態繫結和多型構成了出色的動態特性。


4、基類的有1個虛擬函式,子類還需要申明為virtual嗎?為什麼。
解析:不申明沒有關係的。 不過,我總是喜歡顯式申明,使得程式碼更加清晰。

5、在C++ 程式中呼叫被 C 編譯器編譯後的函式,為什麼要加 extern “C”宣告?
解析:函式和變數被C++編譯後在符號庫中的名字與C語言的不同,被extern “C”修飾的變數和函式是按照C語言方式編譯和連線的。由於編譯後的名字不同,C++程式不能直接呼叫C 函式。C++提供了一個C 連線交換指定符號extern“C”來解決這個問題。

6、如何定義Bool變數的TRUE和FALSE的值。
解析:不知道這個題有什麼陷阱,寫到現在神經已經大了,一般來說先要把TURE和FALSE給定義了,使用#define就可以: #define TURE 1 #define FALSE 0 如果有一個變數需要定義成bool型的,舉個例子:bool a=TURE;就可以了。
false/true是標準C++語言裡新增的關鍵字,而FALSE/TRUE是通過#define,這要用途
是解決程式在C與C++中環境的差異,以下是FALSE/TRUE在windef.h的定義:
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
也就是說FALSE/TRUE是int型別,而false/true是bool型別;所以兩者不一樣的,只不過
我們在使用中沒有這種感覺,因為C++會幫你做隱式轉換。
7、行內函數INline和巨集定義一起使用的區別。
解析:行內函數是在編譯的時候已經做好將對應的函式程式碼替換嵌入到對應的位置,適用於程式碼較少的函式。 巨集定義是簡單的替換變數,如果定義的是有引數的函式形式,引數不做型別校驗。

8、編寫my_strcpy函式,實現與庫函式strcpy類似的功能,不能使用任何庫函式;
正確答案:
char *strcpy(char *strDest, const char *strSrc)
{
if ( strDest == NULL || strSrc == NULL)
return NULL ;
if ( strDest == strSrc)
return strDest ;
char *tempptr = strDest ;
while( (*strDest++ = *strSrc++) != ‘’);
returntempptr ;
}

9、 完成程式,實現對陣列的降序排序
#include
void sort(int array[] );
int main()
{
int array[]={45,56,76,234,1,34,23,2,3}; //數字任//意給出
sort( array );
return 0;
}
void sort( int array[] )
{
inti,j,k;
for(i=1;i<=7;i++) { if(array[i]>array[i-1])
{
k=ARRAY[i];
j=i-1;
do
{
array[j+1]=array[j];
j– ;
}
while(k>array[j]&&j>=0);
array[j+1]=k;
}
}
}

10、ICMP是什麼協議,處於哪一層?
正確答案:Internet控制報文協議,處於網路層(IP層)

11、 C中static有什麼作用
正確答案:
(1)隱藏。 當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性,故使用static在不同的檔案中定義同名函式和同名變數,而不必擔心命名衝突。
(2)static的第二個作用是保持變數內容的持久。儲存在靜態資料區的變數會在程式剛開始執行時就完成初始化,也是唯一的一次初始化。共有兩種變數儲存在靜態儲存區:全域性變數和static變數。
(3)static的第三個作用是預設初始化為0.其實全域性變數也具備這一屬性,因為全域性變數也儲存在靜態資料區。在靜態資料區,記憶體中所有的位元組預設值都是0×00,某些時候這一特點可以減少程式設計師的工作量。

12、Void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
請問執行Test函式會有什麼樣的結果?
正確答案: 可以執行

13、C++特點是什麼,如何實現多型?畫出基類和子類在記憶體中的相互關係。
正確答案:多型的基礎是繼承,需要虛擬函式的支援,簡單的多型是很簡單的。 子類繼承父類大部分的資源,不能繼承的有建構函式,解構函式,拷貝建構函式,operator=函式,友元函式等等

14、 C++中的什麼是多型性? 是如何實現的?
正確答案:多型性是面向物件程式設計語言繼資料抽象和繼承之後的第三個基本特徵。它是在執行時出現的多型性通過派生類和虛擬函式實現。基類和派生類中使用同樣的函式名, 完成不同的操作具體實現相隔離的另一類介面,即把" w h a t"從"h o w"分離開來。多型性提高了程式碼的組織性和可讀性,虛擬函式則根據型別的不同來進行不同的隔離。

15、 關鍵字static的作用是什麼?
正確答案:
這個簡單的問題很少有人能回答完全。在C語言中,關鍵字static有三個明顯的作用:
1). 在函式體,一個被宣告為靜態的變數在這一函式被呼叫過程中維持其值不變。
2). 在模組內(但在函式體外),一個被宣告為靜態的變數可以被模組內所用函式訪問,但不能被模組外其它函式訪問。它是一個本地的全域性變數。
3). 在模組內,一個被宣告為靜態的函式只可被這一模組內的其它函式呼叫。那就是,這個函式被限制在宣告它的模組的本地範圍內使用。 大多數應試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個應試者的嚴重的缺點,因為他顯然不懂得本地化數 據和程式碼範圍的好處和重要性。

16、#define MAX_LEN 500 char arry[MAX_LEN]; cin>>arry; 這段程式碼有問題嗎?若有,請指出並修改;
正確答案:有問題。標頭檔案缺少。 #include <iostream>  using namespace std;

17、delete []arry 和 delete arry 一樣嗎?不一樣請說明;
正確答案:delete []arry 釋放的是多個同一型別的地址空間 Delete arry 釋放的是一個某種型別的地址空間

18、 多型的作用?
正確答案:
主要是兩個:
1)隱藏實現細節,使得程式碼能夠模組化;擴充套件程式碼模組,實現程式碼重用;
2)介面重用,為了類在繼承和派生的時候,保證使用家族中任一類的例項的某一屬性時的正確呼叫。
19、C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。
正確答案:終於最後一題了,容易麼……如果這個測試是一個關於嵌入式的,那麼這道題非常重要!!從詞面上講,volatile的意思是易變的,也就是說,在程式執行過程中,有一些變數可能會被莫名其妙的改變,而優化器為了節約時間,有時候不會重讀這個變數的真實值,而是去讀在暫存器的備份,這樣的話,這個變數的真實值反而被優化器給“優化”掉了,用時髦的詞說就是被“和諧”了。如果使用了這個修飾詞,就是通知編譯器別犯懶,老老實實去重新讀一遍!可能我說的太“通俗”了,那麼我引用一下“大師”的標準解釋: volatile的本意是“易變的” 。 由於訪問暫存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化,但有可能會讀髒資料。當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。 精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。 下面是volatile變數的幾個例子:
1). 並行裝置的硬體暫存器(如:狀態暫存器)
2). 一箇中斷服務子程式中會訪問到的非自動變數(Non-automatic variables)
3). 多執行緒應用中被幾個任務共享的變數 嵌入式系統程式設計師經常同硬體、中斷、RTOS等等打交道,所用這些都要求volatile變數。不懂得volatile內容將會帶來災難。
20、 請簡述以下兩個for迴圈的優缺點
1)for (i=0; i<n; i++)
{
if (condition)
DoSomething();
else
DoOtherthing();
}
2)if (condition)
{
for (i=0; i<n; i++)
DoSomething();
}
else
{
for (i=0; i<n; i++)="" dootherthing();="" }=""
正確答案:
1)優點:程式簡潔。="" 缺點:多執行了n-1次邏輯判斷,並且打斷了迴圈“流水線”作業,使得編譯器不能對迴圈進行優化處理,降低了效率。=""
2)優點:迴圈的效率高。缺點:程式不簡潔。="