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

sizeof 與 strlen 徹底區別:編譯期 vs 運行期、類型 vs 內容

     編輯:關於C語言

sizeof 是運算符 (編譯期),strlen 是函數 (運行期) —— 這是本質區別。本文通過 8 組對比案例,徹底講清兩者在數組、指針、動態內存、結構體等場景下的行為差異。

核心差異速查

特性sizeofstrlen
性質運算符 (關鍵字)函數 (庫函數)
計算時機**編譯期****運行期**
參數類型類型/變量/表達式/函數調用const char* (以 \0 結尾)
返回類型size_tsize_t
語義**佔用內存字節數** (含填充/對齊)**字符串長度** (不含 \0)
數組參數不退化,得整個數組大小退化為指針,得字符串長度
指針參數得指針本身大小 (4/8)得指向字符串長度
動態內存無法得知分配大小能得知字符串長度
結構體含對齊填充的總大小不適用 (非字符串)

八大經典案例實測

1. 靜態字符數組

char str[20] = "0123456789";
strlen(str); // 10
sizeof(str); // 20 (數組定義大小,與內容無關)

2. 指針指向字面量

char *p = "0123456789";
sizeof(p);    // 4/8 (指針大小)
sizeof(*p);   // 1 (char 大小)
strlen(p);    // 10

3. 數組名作函數參數

void foo(char arr[8]) {  // 等價 char *arr
    sizeof(arr); // 4/8 (指針大小!)
    strlen(arr); // 正常工作
}

對策: 同時傳遞長度參數,或結構體封裝 {char *p; size_t len;}。

4. 動態分配數組

char *p = malloc(100);
sizeof(p);     // 4/8 (指針)
strlen(p);     // 不定值 (未初始化內容)
strcpy(p, "hello");
strlen(p);     // 5

5. 結構體對齊

struct { char c; int i; } s;
sizeof(s); // 8 (非 5!編譯器插入 3 字節填充對齊 int)

6. sizeof 類型參數需括號

sizeof(int);    // ✅
sizeof int;     // ✅ (僅變量可省略括號)
sizeof (int);   // ✅

7. 函數參數傳遞陷阱

void fun(unsigned char *p, int len) {
    unsigned char *buf = malloc(len + 1);
    memcpy(buf, p, len); // 必須外部傳長度
}

8. 綜合對比表

char str2[] = "absde";     sizeof=6 (5字符+\0)
char str3[8] = {'a'};      sizeof=8 (定義大小)
char ss[] = "0123456789";  sizeof=11 (10字符+\0)

避坑指南

  1. 求**分配大小/類型大小/結構體大小** → sizeof
  2. 求**字符串可見長度** → strlen
  3. 函數參數為數組 → **必須額外傳長度**,sizeof 失效
  4. 動態內存大小 → 分配時記錄,或用 malloc_usable_size (GNU 擴展)
  5. 格式化輸出 → %zu (C99),別用 %d/%u/%ld
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved