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

C++ 程式設計師筆試題精選匯總:位運算、引用語意、const 正確性

     編輯:C++ 入門

前言

C++ 筆試題旨在短時間內檢測候選人對**語言核心機制、底層運作、現代最佳實踐**的掌握深度。本文精選高頻考題:位運算計數、引用與指標差異、const 引用語意、函式參數傳遞策略,附帶標準答案、評分細則、常見錯誤與延伸思考。

一、位運算經典:計算整數二進制中 1 的個數

題目

int countOnes(int x) {
    int count = 0;
    while (x) {
        count++;
        x = x & (x - 1);
    }
    return count;
}
// 輸入 x = 9999,輸出?

答案:8

原理: x & (x - 1) 能**清除 x 最低位的 1**。迴圈執行次數即 1 的個數 (Brian Kernighan 演算法),時間複雜度 O(1 的個數) 優於 O(位寬)。

驗證: 999910 = 100111000011112,共 8 個 1。

延伸:現代 C++ 寫法


#include  // C++20
int count = std::popcount(static_cast(x)); // 硬體指令 POPCNT,單指令完成
// 或編譯器內建
int count = __builtin_popcount(x); // GCC/Clang/MSVC 支援

二、引用 (Reference) 核心語意與宣告規則

題目:什麼是引用?宣告與使用需注意哪些問題?

標準答案要點

  1. 定義: 引用是**已存在物件的別名**,非新物件,**不佔儲存空間** (編譯器內部通常以指標實現,但語義上無指標算術)。
  2. 初始化強制: 宣告時**必須初始化**,且**不可重新綁定** (綁定後終生指向同一物件)。
  3. 非型別: 引用本身不是型別,無法建立引用陣列、引用指標、引用的引用 (C++ 標準禁止,但 using Ref = int&; 別名合法)。
  4. 操作透明: 對引用的任何操作 (賦值、取址、sizeof、型別轉換) 直接作用於被引用物件。

程式碼示範


int a = 10;
int& ref = a;      // 正確:初始化綁定 a
// int& ref2;      // 錯誤:未初始化
// int& ref3 = 10; // 錯誤:非常數引用不能綁定暫時物件
const int& cref = 10; // 正確:const 引用延長暫時物件壽命

ref = 20;          // a 變為 20
int b = 30;
ref = b;           // 賦值操作:a = 30,而非 ref 綁定 b!
// int& ref4 = ref; // 合法:ref4 也綁定 a (引用的引用透過 typedef/using 間接實現)

三、引用作為函式參數的三大特點

特點說明對比:值傳遞 / 指標傳遞
1. 零副本、直接操作實參記憶體中不產生實參副本,直接讀寫原物件。大型物件傳遞極高效。值傳遞:複製構造、析構開銷大。指標:需解參考、可為 null。
2. 語法簡潔、無解參考雜訊函式內像操作區域變數一樣操作實參,*ptr、ptr-> 雜訊全無。指標:頻繁 */->,易寫錯、難閱讀。
3. 呼叫端無需取址呼叫 func(obj) 而非 func(&obj),介面更乾淨。指標:呼叫端必須 &,洩露「可修改」意圖。

效能註記

對於小型型別 (int, double, 指標大小),**值傳遞通常比引用更快** (寄存器傳遞、無間接存取)。引用優勢在於**大型物件、不可複製型別、需修改實參、多型基類參數**。

四、const 引用:何時使用、為何關鍵

題目:何時需要「常引用」?

答案:

當**同時滿足**以下條件:

  1. 需避免大型物件複製開銷 (效能)。
  2. 函式**不應修改**實參 (語意/安全)。
  3. 需接受**暫時物件/字面常量/右值** (通用性)。

程式碼示範


void printString(const std::string& s) { // 接受 lvalue、rvalue、字面常量
    std::cout << s << '\n';
}

std::string foo() { return "temp"; }

printString("hello world");        // 字面常量 → 暫時 std::string → 綁定 const&
printString(foo());                // 函式返回右值 → 綁定 const&
printString(std::string("temp"));  // 顯式暫時物件 → 綁定 const&

// 非 const 引用無法綁定以上三者 → 編譯錯誤
// void bad(std::string& s); bad("hello"); // Error

最佳實踐:參數傳遞決策樹 (C++11/14/17/20)


// 1. 需修改實參 → 非 const 左值引用 (T&)
// 2. 不修改、型別小 (≤ 2*sizeof(void*)) 且可複製 → 值傳遞 (T)
// 3. 不修改、型別大或不可複製 → const 左值引用 (const T&)
// 4. 需轉移所有權 (C++11) → 右值引用 (T&&) 或 by-value + std::move
// 5. 萬能轉發模板 → 轉發引用 (T&&) + std::forward

五、常見筆試陷阱題與解析

陷阱 1:引用作為返回值


int& bad() {
    int x = 10;
    return x; // 錯誤:返回區域變數引用 → 懸空引用
}

int& good() {
    static int x = 10; // 靜態儲存期
    return x; // 正確
}

陷阱 2:條件運算子返回引用


int a = 1, b = 2;
(int&) (true ? a : b) = 10; // C++ 允許條件運算子返回左值引用
// a 變為 10

陷阱 3:const 引用綁定暫時物件壽命延長


const std::string& ref = std::string("temp"); // 暫時物件壽命延長至 ref 作用域結束
// 但:
const std::string& ref2 = foo(); // foo() 返回值 (右值) 同樣延長
// 然而:
const std::string& ref3 = getStringRef(); // 若 foo 返回 const std::string&,不延長!

六、筆試高分策略

  1. 碼寫在紙上/白板: 無 IDE 補全,練習手寫標準庫介面、const 正確性、模板語法。
  2. 邊寫邊講: 面試官看重思維過程,「這裡用 const& 是因為...」、「這裡需檢查 nullptr 因為...」。
  3. 標註複雜度與 UB: 主動說出時間/空間複雜度、潛在未定義行為、例外安全等級。
  4. 現代 C++ 加分: 能自然使用 auto, nullptr, constexpr, std::move, std::forward, string_view, span, optional, variant、概念約束。

結語

C++ 筆試題看似考語法細節,實考**語言設計哲學內化程度**。《Effective C++》條款 1-3 (視 C++ 為語言聯邦、優先用 const/reference、理解物件生命週期) 是所有筆試題的底層邏輯。精準掌握「位運算技巧、引用/指標/值傳遞三選一決策、const 正確性、暫時物件壽命延長、RAII 資源管理」,並能手寫無誤的工業級程式碼片段,即可在筆試中脫穎而出。

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