首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ 面試經典題目深度解析:12 道考察核心功力的必考題

     編輯:關於C語言

題目來源與價值

精選自資深面試題庫,覆蓋對象模型、類型轉換、模板、STL、內存管理、未定義行為等 C++ 核心硬骨頭。適合面試準備、自我檢測、技術深度鞏固。

逐題深度解析

1. 字符串/數組/指針比較陷阱

char str1[] = "abc", str2[] = "abc";
const char str3[] = "abc", str4[] = "abc";
const char* str5 = "abc", *str6 = "abc";

cout << (str1==str2) << (str3==str4) << (str5==str6);  // false false true

解析:

  • 數組 str1/str2 各自分配棧空間,地址不同
  • const 數組同理,const 只影響可修改性
  • 字符指針 str5/str6 指向靜態存儲區同一字符串常量 "abc" (編譯器合併優化),地址相同

2. sizeof 在函數參數中的退化

void UpperCase(char str[]) {
    for (size_t i=0; i

鐵律:函數參數 char str[] 退化為 char*,sizeof 失效。需額外傳長度或用 std::string/std::span。

3. 隱式類型轉換的四種途徑

非內建類型 B → A 隱式轉換發生於:

  1. class B : public A (公有繼承,含間接)
  2. class B { operator A(); } (轉換函數)
  3. class A { A(const B&); } (非 explicit 建構函數)
  4. A& operator=(const A&) (賦值操作,廣義轉換)

4. 默認建構函數聲明陷阱

Test b();  // 錯誤!這是函數聲明,非對象構造
Test b;    // 正確:調用默認建構函數

「最令人惱火的解析」:任何能被解析為聲明的語句,就會被解析為聲明。

5. 三元運算符類型一致性要求

cout << (true ? 1 : "1");  // 編譯錯誤:int 與 const char* 類型不兼容

?: 要求第二、三操作數類型相同,或可隱式轉換至公共類型。

6. 編譯期常量與 VLA 區別

unsigned int const size1 = 2;  char str1[size1];  // OK: 編譯期常量
unsigned int const size2 = temp; char str2[size2];  // 錯誤: size2 非編譯期常量 (C99 VLA 除外,C++ 不支持)

C++ 要求陣列大小為編譯期常量表達式。

7. 無符號類型反向遍歷陷阱

for (vector::size_type i=v.size()-1; i>=0; --i)  // 死循環!
// size_type 為 unsigned,i>=0 永真,i-- 從 0 變最大值

修正:for (auto i = v.size(); i-- > 0; ) 或 for (int i = v.size()-1; i >= 0; --i)。

8. 建構函數委托誤區 (C++11 前)

CLS() { CLS(0); }  // 錯誤!創建臨時對象,不初始化 this
// 正確 (C++11): CLS() : CLS(0) {}
// 正確 (舊標準): CLS() { m_i = 0; } 或用 init 函數

函數體內調用建構函數只是創建臨時對象,不進行成員初始化。

9. 空類編譯器自動生成的 6 大成員函數

class Empty {
public:
    Empty();                    // 默認建構函數
    Empty(const Empty&);        // 拷貝建構函數
    ~Empty();                   // 解構函數
    Empty& operator=(const Empty&); // 拷貝賦值
    Empty* operator&();         // 取址
    const Empty* operator&() const; // const 取址
};

10. 強制轉換 vs 重新解釋轉換

float a = 1.0f;
(int)a;     // 值轉換:構造新 int,值為 1
(int&)a;    // 重新解釋:將 a 的 4 字節按 int 讀取,值為 1065353216 (IEEE 754 0x3F800000)
(float b = 0.0f; (int)b == (int&)b)  // true:0.0 和 0 位模式全 0

展示值語義與位模式語義的本質差異。

11. vector 迭代器失效與 erase 陷阱

for (auto it = v.begin(); it != v.end(); ++it)
    if (*it == 2) v.erase(it);  // 錯誤:erase 導致後續元素前移,it 失效,漏檢

修正:it = v.erase(it) (C++11 返回下一有效迭代器) 或 if (*it == 2) { it = v.erase(it); } else { ++it; }。

12. memcpy 實現與記憶體重疊處理

void* mymemcpy(void* dest, const void* src, size_t n) {
    char* d = (char*)dest;
    const char* s = (const char*)src;
    if (d > s && d < s + n)  // 重疊且 dest 在 src 後:逆向拷貝
        for (size_t i = n; i-- > 0; ) d[i] = s[i];
    else  // 正向拷貝
        for (size_t i = 0; i < n; ++i) d[i] = s[i];
    return dest;
}

標準 memcpy 行為未定義於重疊區域,memmove 保證正確處理重疊。面試常考察此邊界條件意識。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved