秋招C++八股--關鍵字、運算符相關(持續更新)

晚晚linux服務器 發佈 2023-11-22T01:23:26.351512+00:00

bad_typeid:使用typeid運算符,如果其操作數是一個多態類的指針,而該指針的值為 NULL,則會拋出此異常,例如:bad_cast:在用 dynamic_cast 進行從多態基類對象到派生類的引用的強制類型轉換時,如果轉換是不安全的,則會拋出此異常 bad_alloc:在用 new 運算符進行動態內存分配時,如果沒有足夠的內存,則會引發此異常。

整理全網c++1000道面試題。文章所展現為統計高頻題及答案。



需要1000道面試PDF,【「連結」】

1 strlen和sizeof區別?

strlen和sizeof是C++中用於處理字符串和計算內存大小的操作。

  1. strlen函數:
  2. strlen函數是C標準庫中的函數,用於計算字符串的長度,即字符串中字符的個數(不包括結尾的空字符'\0')。
  3. 它接受一個以'\0'結尾的字符數組作為參數,並返回該字符串的長度
  4. strlen函數通過遍歷字符數組來計算長度,直到遇到空字符為止。
  5. sizeof運算符:
  6. sizeof是C++中的運算符,用於計算對象或類型的大小,即占用的內存字節數
  7. 它可以用於計算各種類型的大小,包括基本類型、自定義類型和數組等。
  8. sizeof運算符在編譯時求值,返回的結果是一個常量表達式,在編譯階段就可以確定。

區別:

  • strlen用於計算以'\0'結尾的字符數組的長度,即字符串的長度,返回的是字符個數。
  • sizeof用於計算對象或類型的大小,返回的是占用的內存字節數。

需要注意的是,strlen計算的是字符串的實際長度,而sizeof計算的是類型或對象占用的內存大小。因此,在使用時要注意選擇適當的操作,以滿足具體的需求。

int main()
{
    const char* str = "name"; 4
    sizeof(str); // 取的是指針str的長度,是8
    strlen(str); // 取的是這個字符串的長度,不包含結尾的 \0。大小是4
    return 0; 
}

2 C++ 中的異常處理方法

在程序執行過程中,由於程式設計師的疏忽或是系統資源緊張等因素都有可能導致異常,任何程序都無法保 證絕對的穩定,常見的異常有: 數組下標越界

除法計算時除數為0 動態分配空間時空間不足 ... 如果不及時對這些異常進行處理,程序多數情況下都會崩潰。

1.try、throw和catch關鍵字

代碼中,對兩個數進行除法計算,其中除數為0。可以看到以上三個關鍵字,程序的執行流程是先執行 try包裹的語句塊,如果執行過程中沒有異常發生,則不會進入任何catch包裹的語句塊,如果發生異 常,則使用throw進行異常拋出,再由catch進行捕獲,throw可以拋出各種數據類型的信息,代碼中使 用的是數字,也可以自定義異常class。catch**根據*throw*拋出的數據類型進行精確捕獲(不會出現類型 轉換),如果匹配不到就直接報錯,可以使用**catch(...)的方式捕獲任何異常(不推薦)。當然,如果catch了異常,當前函數如果不進行處理,或者已經處理了想通知上一層的調用者,可以在catch裡面再throw異常。

#include <iostream>
using namespace std;

int main() {
    double m = 1, n = 0;
    try {
        cout << "before dividing." << endl;
        if (n == 0)
            throw - 1;    // 拋出int型異常
        else if (m == 0)
            throw - 1.0;  // 拋出double型異常
        else
            cout << m / n << endl;
        cout << "after dividing." << endl;
    }
    catch (double d) {
        cout << "catch (double)" << d << endl;
    }
    catch (...) {
        cout << "catch (...)" << endl;
    }
    cout << "finished" << endl;
    return 0;
}

2.函數的異常聲明列表

有時候,程式設計師在定義函數的時候知道函數可能發生的異常,可以在函數聲明和定義時,指出所能拋出 異常的列表,寫法如下:

int fun() throw(int,double,A,B,C){...}; 

這種寫法表名函數可能會拋出int,double型或者A、B、C三種類型的異常,如果throw中為空,表明不 會拋出任何異常,如果沒有throw則可能拋出任何異常

3.C++ 標準異常類

bad_typeid:使用typeid運算符,如果其操作數是一個多態類的指針,而該指針的值為 NULL,則會拋出此異常,例如:

#include <iostream>
#include <typeinfo>

using namespace std;

class A {
public:
    virtual ~A();
};

int main() {
    A* a = nullptr;
    try {
        cout << typeid(*a).name() << endl; // Error condition
    } catch (bad_typeid) {
        cout << "Object is NULL" << endl;
    }
    return 0;
}

bad_cast:在用 dynamic_cast 進行從多態基類對象(或引用)到派生類的引用的強制類型轉換時,如果轉換是不安全的,則會拋出此異常 bad_alloc:在用 new 運算符進行動態內存分配時,如果沒有足夠的內存,則會引發此異常

out_of_range:用 vector 或 string的at 成員函數根據下標訪問元素時,如果下標越界,則會拋出此異常

3 初始化和賦值的區別

初始化是在對象創建時進行的賦值,使用構造函數或拷貝構造函數;賦值是在對象已存在的情況下進行的重新賦值,使用賦值操作符函數。兩者的調用方式和對象狀態有所不同。

class A {
public:
    int num1;
    int num2;
public:
    A(int a = 0, int b = 0) :num1(a), num2(b) {};
    A(const A& a) {};
    //重載 = 號操作符函數 
    A& operator=(const A& a) {
        num1 = a.num1 + 1;
        num2 = a.num2 + 1;
        return *this
    };
};
int main() {
    A a(1, 1);
    A a1 = a; //拷貝初始化操作,調用拷貝構造函數 
    A b;
    b = a;//賦值操作,對象a中,num1 = 1,num2 = 1;對象b中,num1 = 2,num2 = 2 
    return 0;
}
關鍵字: