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

C++ sizeof 操作符深度解析:編譯期計算、類型推導與常見陷阱

     編輯:C++ 入門

前言:sizeof 不是函數,也不是普通運算符

sizeof 是 C++ 中極具特殊性的關鍵字。它在編譯期求值,結果為常量表達式。理解其「編譯期替換」本質,是避開經典陷阱(如副作用不執行)的關鍵。本文將系統講解其定義、兩種語法形式、類型推導規則與實戰陷阱。

核心定義與本質

  • 功能:返回類型或表達式類型所佔存儲字節數 (單位:char 大小,即 1 字節)。
  • 返回類型:std::size_t (無符號整型)。
  • 求值時機:編譯期。編譯器將 sizeof(...) 直接替換為常數。
  • 不屬於:函數(可無括號調用)、一元運算符(不支持鏈式表達式)、運行時操作。

兩種標準語法形式

形式語法示例說明
操作數為類型sizeof(類型名)sizeof(int), sizeof(MyClass)必須加括號。sizeof int 非法。
操作數為表達式sizeof 表達式 或 sizeof(表達式)sizeof x, sizeof(x), sizeof(1+2)括號可選但建議始終加上,避免歧義。

黃金法則:無論對類型還是表達式,統一使用 sizeof( ... ) 形式,永遠正確且清晰。

編譯期求值的鐵律:表達式不執行,只推導類型

這是最核心、最易踩坑的特性。

經典陷阱:副作用不發生


int a = 0;
std::cout << sizeof(a = 3) << std::endl; // 輸出 4 (int 大小)
std::cout << a << std::endl;             // 輸出 0 !!! 賦值未執行

原因:編譯器只分析表達式 a = 3 的類型(賦值表達式類型為左值類型 int),直接替換為 4。賦值指令從未生成機器碼。

推導規則示例


sizeof(int)        // 4 (32位系統)
sizeof(1 == 2)     // 1 (bool 類型,== 返回 bool)
sizeof('c')        // 4 (字符字面量類型為 int,C++ 特性)
sizeof("str")      // 4/8 (字符串字面量類型為 const char[N],退化為指針)
// 注意:sizeof 對數組名不退化
int arr[10];
sizeof(arr)        // 40 (int[10] 完整類型大小)
sizeof(&arr)       // 4/8 (指針大小)

sizeof 不支持鏈式操作

一元運算符可鏈式:++++i (雖無意義但合法)。sizeof 不行:


// sizeof sizeof int // 編譯錯誤
// 原因:sizeof 後需跟類型或表達式,sizeof int 本身非類型/表達式

實戰應用場景

  1. 編譯期斷言:static_assert(sizeof(MyStruct) == 16, "Alignment broken");
  2. 數組元素計數:int n = sizeof(arr) / sizeof(arr[0]); (僅適用於作用域內的真數組,不適用指針)。
  3. 類型大小比較/元編程:模板元編程中分發邏輯。
  4. 結構體對齊/填充分析:驗證 #pragma pack 或屬性效果。

C++11/17 現代擴展

  • alignof(T):獲取類型對齊要求 (編譯期常量),配合 sizeof 完整描述內存佈局。
  • std::size(arr) (C++17, <iterator>):安全獲取數組/容器大小,替代宏。
  • std::byte (C++17):字節操作類型,語義比 char/unsigned char 更清晰。

總結

sizeof 是編譯期的「類型尺子」。牢記三點:1. 編譯期求值,表達式不執行;2. 統一用 sizeof(...) 語法;3. 結果為 size_t 常量表達式。 理解其本質,能寫出更安全的泛型代碼、元編程邏輯與內存佈局控制代碼。

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