C/C++錯題集__C++

來源:互聯網
上載者:User

1.  charc = '\72'; 中的\72代表一個字元,72是八位元,代表ASCII碼字元“:”。

2.  10*a++ 中a先進行乘法運算再自增(筆試中經常喜歡出這類運算子優先順序容易混淆的輸出問題)。

3.  const和static的作用 
太常見的問題了,下面給出一個較詳細的參考答案:

static關鍵字:

1)函數體內static變數的作用範圍為函數體。不同於auto變數。該變數的記憶體只被分配一次。因此其值在下次調用時仍維持上次的值。

2)在模組內的static全域變數可以被模組內的所有函數訪問。但不能被模組外的其他函數訪問。

3)在模組內的static函數只可被這一模組內的其它函數調用。這個函數的使用範圍被限制在聲明它的模組內。

4)在類中的static成員變數屬於整個類所有,對類的所有對象只有一份複製。

5)在類中的static成員函數屬於整個類所有,這個函數不接受this指標,因而只能訪問類的static成員變數。

const關鍵字:

1)欲阻止一個變數被改變,可以使用const關鍵字。在定義該const變數時,通常需要對它進行初始化。因為以後就沒有機會再改變它了。

2)對指標來說,可以指定指標的本身為const,也可以指定指標所指向的數為const。或二者同時為const。

3)在一個函數的聲明中,const可以修飾形參,表明它是一個輸入參數。在函數內不能改變其值。

4)對於類的成員函數,若指定其為const類型。則表明其是一個常量函數。不能修改類的成員變數。

5)對於類的成員函數,有時候必須指定其傳回值為const類型。以使得其傳回值不為“左值”。

4.  注意sizeof不是函數而是運算子,所以在計算變數所佔用空間大小時,括弧是可以省略的,但在計算類型大小時括弧則不能省略,比如int i = 0; 則sizeof int是錯誤的。

5.  有1,2,…,n的無序數組,求排序演算法,並且要求時間複雜度為O(n),空間複雜度O(1),使用交換,而且一次只能交換兩個數。

#include <stdio.h>

 

int main(){

    inta[] = {10, 6, 9, 5, 2, 8, 4, 7, 1, 3};

    inti, tmp;

    intlen = sizeof(a) / sizeof(a[0]);

    for(i= 0; i < len;) {

       tmp = a[a[i] - 1];

       a[a[i] - 1] = a[i];

       a[i] = tmp;

       if(a[i] == i + 1) i++;

    }

    for(i= 0; i < len; ++i)

       printf("%d ",a[i]);

    printf("\n");

    return0;

}

6.  易誤解:如果inta[5], 那麼a與&a是等價的,因為兩者地址相同。 
解答:一定要注意a與&a是不一樣的,雖然兩者地址相同,但意義不一樣,&a是整個數組對象的首地址,而a是數組首地址,也就是a[0]的地址,a的類型是int[5],a[0]的類型是int,因此&a+1相當於a的地址值加上sizeof(int) * 5,也就是a[5],下一個對象的地址,已經越界了,而a+1相當於a的地址加上sizeof(int),即a[1]的地址。

7.  如何將一個小數分解成整數部分和小數部分。 
要記得利用標頭檔中的庫函數modf,下面是函數原型(記住一些實用的庫函數,避免自己重寫):

double modf(doublenum, double *i); // 將num分解為整數部分*i和小數部分(傳回值決定)

8.  可作為函數重載判斷依據的有:參數個數、參數類型、const修飾符; 
不可以作為重載判斷依據的有:傳回型別。

9.  程式輸出題:

 inta[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

 int*p = &(a + 1)[3];

 printf("%d\n", *p);

輸出:5 
說明:因為a+1指向a的第二個元素,[3]表示再向後移動3個元素。

10.程式輸出題:

 charstr1[] = "abc";

 charstr2[] = "abc";

 constchar str3[] = "abc";

 constchar str4[] = "abc";

 constchar *str5 = "abc";

 constchar *str6 = "abc";

 char*str7 = "abc";

 char*str8 = "abc";

 cout<< (str1 == str2) << endl;

 cout<< (str3 == str4) << endl;

 cout<< (str5 == str6) << endl;

 cout<< (str7 == str8) << endl;

輸出:0 0 1 1 
說明:輸出str1~str8的地址為:

0x23aa80 
0x23aa70 
0x23aa60 
0x23aa50 
0x23aa48 
0x23aa40 
0x23aa38 
0x23aa30

輸出str1~str8內容“abc”的儲存地址為:

0x23aa80 
0x23aa70 
0x23aa60 
0x23aa50 
0x100403030 
0x100403030 
0x100403030 
0x100403030

可以發現str1~str4中的內容是存在棧上,地址各不相同,而str5~str8的內容都是儲存在常量區,所以地址都相同。

注意:

char *str ="abc";

printf("%p\n",str1); 

cout<< &str1 << endl;

上面列印的是字串 “abc”的地址,下面列印的是 str1 變數的地址。

11.C的結構體和C++結構體的區別

(1)C的結構體內不允許有函數存在,C++允許有內部成員函數,且允許該函數是虛函數。所以C的結構體是沒有建構函式、解構函式、和this指標的。 
(2)C的結構體對內部成員變數的存取權限只能是public,而C++允許public,protected,private三種。 
(3)C語言的結構體是不可以繼承的,C++的結構體是可以從其他的結構體或者類繼承過來的。

以上都是表面的區別,實際區別就是面向過程和物件導向編程思路的區別:

C的結構體只是把資料變數給包裹起來了,並不涉及演算法。 
而C++是把資料變數及對這些資料變數的相關演算法給封裝起來,並且給對這些資料和類不同的存取權限。 
C語言中是沒有類的概念的,但是C語言可以通過結構體內建立函數指標實現物件導向思想。

12.如何在類中定義常量成員並為其初始化。 
解答:只能在初始化列表裡對const成員初始化,像下面這樣:

class CBook{

public:

    constdouble m_price;

   CBook() :m_price(8.8) { }

};

下面的做法是錯誤的:

class CBook{

public:

    constdouble m_price;

   CBook() {

       m_price = 8.8;

    }

};

而下面的做法雖未報錯,但有個warning,也不推薦:

class CBook{

public:

    constdouble m_price = 8.8; // 注意這裡若沒有const則編譯出錯

   CBook() { }

};

13.在定義類的成員函數時使用mutable關鍵字的作用是什麼。 
解答:當需要在const方法中修改對象的資料成員時,可以在資料成員前使用mutable關鍵字,防止出現編譯出錯。例子如下:

class CBook{

public:

    mutabledouble m_price;  // 如果不加就會出錯

   CBook(double price) :m_price(price) { }

    doublegetPrice() const; // 定義const方法

};

doubleCBook::getPrice() const {

   m_price = 9.8;

    returnm_price;

}

14.建構函式、拷貝建構函式、解構函式的調用點和順序問題,如下面這個例子輸出是什麼。

class CBook{

public:

   CBook() {

       cout << "constructoris called.\n";

    }

   ~CBook() {

       cout << "destructor iscalled.\n";

    }

};

 

voidinvoke(CBook book) { // 對象作為函數參數,如果這裡加了個&就不是了,因為加了&後是引用方式傳遞,形參和實參指向同一塊地           

                          // 址,就不需要建立臨時對象,也就不需要調用拷貝建構函式了

    cout<< "invoke is called.\n";

}

 

int main(){

   CBook c;

   invoke(c);

}

解答:注意拷貝建構函式在對象作為函數參數傳遞時被調用,注意是對象執行個體而不是對象引用。因此該題輸出如下:

constructor is called.

invoke is called.

destructor is called.  // 在invoke函數調用結束時還要釋放拷貝建構函式建立的臨時對象,因此這裡還調用了個解構函式

destructor is called. 

引申:拷貝建構函式在哪些情況下被調用。 
(1)函數的參數為類對象且參數採用值傳遞方式; 
(2)將類對象做為函數的傳回值。

15.C++中的explicit關鍵字有何作用。 
解答:禁止將建構函式作為轉換函式,即禁止建構函式自動進行隱式類型轉換。 
例如CBook中只有一個參數m_price,在構建對象時可以使用CBook c = 9.8這樣的隱式轉換,使用explicit防止這種轉換髮生。

16.在C++中,如果確定了某一個建構函式的建立過程,在該建構函式中如果調用了其它重載的建構函式,它將不會執行其它建構函式的初始化列表部分代碼,而是執行函數體代碼,此時已經退化成普通函數了。例子說明如下:

class CBook{

public:

    doublem_price;

   CBook() {

       CBook(8.8);

    }

   CBook(double price) : m_price(price) { }

};

int main(){

   CBook c;

    cout<< c.m_price << endl;  // 此時並不會輸出理想中的8.8

}

17.待用資料成員只能在全域地區進行初始化,而不能在類體中進行(建構函式中初始化也不行),且待用資料成員不涉及對象,因此不受類訪問限定符的限制。 
例子說明如下:

class CBook{

public:

    staticdouble m_price;

};

doubleCBook::m_price = 8.8;  // 只能在這初始化,不能在CBook的建構函式或直接初始化

18.C++中可以重載的運算子:new/delete、new[]/delete[]、++等。 
可以重載的運算子:、.、::、?:、sizeof、typeid、.、**、不能改變運算子的優先順序。

引申:重載++和–時是怎麼區分首碼++和尾碼++的。 
例如當編譯器看到++a(先自增)時,它就調用operator++(a); 
但當編譯器看到a++時,它就調用operator++(a,int)。即編譯器通過調用不同的函數區別這兩種形式。

19.C++的多態性分為靜態多態和動態多態。 
靜態多態性:編譯期間確定具體執行哪一項操作,主要是通過函數重載和運算子多載來實現的; 
動態多態性:運行時確定具體執行哪一項操作,主要是通過虛函數來實現的。

20.虛函數原理考點,例如下面程式的輸出是什麼。

class A {

public:

    virtualvoid funa();

    virtualvoid funb();

    voidfunc();

    staticvoid fund();

    staticint si;

private:

    inti;

    charc;

};

問:sizeof(A) = ?

解答: 
關於類佔用的記憶體空間,有以下幾點需要注意: 
(1)如果類中含有虛函數,則編譯器需要為類構建虛函數表,類中需要儲存一個指標指向這個虛函數表的首地址,注意不管有幾個虛函數,都只建立一張表,所有的虛函數地址都存在這張表裡,類中只需要一個指標指向虛函數表首地址即可。 
(2)類中的靜態成員是被類所有執行個體所共用的,它不計入sizeof計算的空間 
(3)類中的普通函數或靜態普通函數都儲存在棧中,不計入sizeof計算的空間 
(4)類成員採用位元組對齊的方式分配空間

答案:12(32位系統)或16(64位系統)

21.虛繼承的作用是什麼。 
在多繼承中,子類可能同時擁有多個父類,如果這些父類還有相同的父類(祖先類),那麼在子類中就會有多份祖先類。例如,類B和類C都繼承與類A,如果類D派生於B和C,那麼類D中就會有兩份A。為了防止在多繼承中子類存在重複的父類情況,可以在父類繼承時使用虛函數,即在類B和類C繼承類A時使用virtual關鍵字,例如: 
class B : virtual public A 
class C : virtual public A 
註:因為多繼承會帶來很多複雜問題,因此要慎用。

22、在C++中參數傳遞只有值傳遞和引用傳遞,地址傳遞指的是指標傳遞,而指標傳遞本質上也是值傳遞(指標值)

23、假設x=9981,下面函數的傳回值是。

    int func(x)

{

    int countx=0;

    while(x)

    {

        countx++;

        x=x&(x-1);

    }

    return countx;

}

先轉2進位為10011011111101,每次x&(x-1)會讓原來的1(從低位到高位依次)變為0。一共10個1,10次迴圈之後x為0,退出迴圈。

24、在C++中的結構體可以有建構函式

C中的結構體沒有函數 但是C++的結構體可以有函數;這是C與C++結構體的區別。

C++的結構體可以被類取代,因為類相對於結構體 具有封裝性等優勢。

C++中結構體與類的區別:

結構體中的成員存取權限不聲明時候預設是 公開的;而類 是私人的

25、靜態多態(早綁定),如函數重載

    動態多態(晚綁定),如虛函數,繼承

26、父類指標指向子類對象,如果子類有指標資料成員,刪除父類對象時會造成記憶體流失,解決方案時,將父類的解構函式定義成虛解構函式

27、virtual 不能修飾靜態成員函數、內嵌函式和建構函式

28、父類和子類定義了同名的函數就是函數的隱藏

    子類繼承父類的虛函數就是函數的覆蓋

29、沒有資料成員的類,執行個體化時也有一個位元組記憶體單元

30、虛函數表佔用4個位元組記憶體

31、繼承抽象類別時,如果沒有對純虛函數重新定義,則子類也是抽象類別

32、ctrl+k+u取消注釋

33、預設建構函式:class::class(){};

34、僅含有純虛函數的類是介面類,沒有資料成員,只有純虛成員函數

35、typeid(*obj).name()列印obj對象的類型

36、dynamic_cast注意事項:

只能應用與指標和引用的轉換

要轉換的類型中必須包含虛函數

轉換成功返回子類的地址,失敗返回NULL

37、typeid注意事項:typeid返回一個type_info對象的引用

    如果想通過基類的指標或的衍生類別的資料類型,基類必須帶有虛函數

    只能擷取對象的實際類型

38、常見的異常:

數組下標越界,除數為0,記憶體不足(記憶體流失)

C++遠征之模板篇

39、類的靜態成員函數可以調用待用資料成員,但是不能調用非待用資料成員和非靜態成員函數

    待用資料成員必須單獨初始化

    待用資料成員只有一份,且不依賴對象而存在

    靜態成員函數不能加const

40、前置:Coordinate& operator ++();

    後置:Coordinate operator++(int);

41、一元運算子重載,如果是類的成員函數,則不需要形參,如果是類的友元函數,則需要一個類類型的形參。

    二元運算子重載,如果是類的成員函數,則需要一個形參,如果是類的友元函數,則需要兩個形參。

42、索引運算子多載不可以是友元函數

43、大端模式:資料低位放在記憶體高位

    小端模式:資料低位放在記憶體低位

44、建構函式中,成員變數一定要通過初始化列表來初始化的是:引用、const和沒有預設建構函式的成員對象

45、不允許通過函數傳回值重載函數

46、由多個源檔案組成的C程式,經過編輯、預先處理、編譯,連結等階段會產生最終的可執行程式。下面哪個階段可以發現被調用的函數未定義。連結
47、對於內部資料類型來說,傳回值是否是常量並沒有關係處理使用者定義的類型時,傳回值是常量是很重要的,如果一個函數返回一個類對象的值,其值是常量,那麼這個函數的傳回值不能是一個左值(即它不能被賦值,也不能被修改)

48、

          32位系統    64位系統  (單位Bytes)  

char         1       1

short          2        2

int         4        4 

指標             4           8

long           4        8

float   

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.