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

C/C++ 中 sizeof 與 strlen 的區別深度解析

     編輯:關於C語言

核心區別一覽

特性sizeofstrlen
本質編譯期運算符運行期庫函數
參數類型任意類型/變量/表達式僅限 char*(以 '\0' 結尾)
返回值類型/對象佔用字節數(size_t)字符串長度(不含結束符)
計算時機編譯期確定運行時遍歷計算
數組參數不退化,得整個數組大小退化為指針,得指針大小
結構體/對象返回實際佔用內存(含對齊填充)不適用
動態分配內存返回指針大小,無法得知分配大小若指向 C 字符串則返回長度

典型示例

char str[20] = "0123456789";
int a = strlen(str); // a = 10,字符串實際長度
int b = sizeof(str); // b = 20,數組分配空間大小

char *p = "0123456789";
sizeof(p);   // 4/8(指針大小,視平台 32/64 位)
sizeof(*p);  // 1(char 類型大小)
strlen(p);   // 10(字符串長度)

深度解析

1. sizeof 是運算符,非函數

  • 對類型用法:sizeof(int)、sizeof(double) —— 必須加括號。
  • 對變量/表達式用法:sizeof x、sizeof(x) —— 括號可選。
  • 可用於函數調用表達式:short f(); sizeof(f()) 返回 sizeof(short),函數不會真正調用。

2. strlen 需以 '\0' 結尾

  • 從指針開始逐字節掃描,遇到 '\0' 停止,返回計數。
  • 若內存中無 '\0',會越界讀取導致未定義行為。
  • 只能用於 C 風格字符串,不能直接用於 std::string(需 .c_str() 或 .size())。

3. 數組作函數參數會退化為指針

void fun(char arr[8])  // 等價於 void fun(char *arr)
void fun(char arr[])   // 等價於 void fun(char *arr)

函數內 sizeof(arr) 返回指針大小(4/8),而非數組大小。解決方案:額外傳遞長度參數,或使用模板/引用保持數組類型:

template
void fun(char (&arr)[N]) { /* sizeof(arr) == N */ }

4. 結構體與對齊

struct A { char c; int i; }; // 通常 sizeof(A) == 8(含 3 字節填充)

sizeof 返回編譯器分配的完整大小,包含對齊填充字節。

5. 靜態 vs 動態數組

  • 靜態數組:char a[100]; sizeof(a) == 100。
  • 動態數組:char *p = new char[100]; sizeof(p) == 4/8(指針大小),無法通過 sizeof 獲取 100。

最佳實踐建議

  1. 獲取類型/變量佔用內存 → sizeof。
  2. 獲取 C 字符串可見字符長度 → strlen。
  3. C++ 中優先使用 std::string、std::vector、std::array,分別提供 .size()、.size()、.size(),避免手動計算。
  4. 函數接口傳遞數組時,同時傳遞長度 或使用容器/視圖(std::span C++20)。

總結

sizeof 是編譯期運算符,反映類型/對象在內存中的佔用大小;strlen 是運行期函數,專門統計以 '\0' 結尾的字符串長度。兩者應用場景截然不同,混淆會導致嚴重邏輯錯誤(如緩衝區溢出、截斷)。理解數組退化、指針大小、動態分配限制,是寫出健壯 C/C++ 代碼的基礎。

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