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

C語言 sizeof 與 strlen 核心區別深度解析:運算符 vs 函數、編譯期 vs 運行期

     編輯:關於C語言

前言:一道經典面試題的背後

sizeof 與 strlen 是 C 語言中最易混淆、最高頻考察的知識點。本質上:sizeof 是編譯期運算符,求類型/表達式佔用字節數;strlen 是運行期庫函數,計算以 '\0' 結尾的字串長度。 本文從本質、用法、陷阱、實戰五個維度徹底釐清。

一、本質區別對比表

維度sizeofstrlen
性質單目運算符(關鍵字)標準庫函數 (<string.h>)
計算時機編譯期(常量表達式)運行期(遍歷記憶體)
參數類型類型、變量、表達式、函數調用僅 const char*(字串指針)
結果含義佔用存儲空間(字節數,含 '\0')字串有效字符數(不含 '\0')
括號要求類型必加括號;變量/表達式可選必須加括號(函數調用)
對數組名整個數組大小退化為指針,計算字串長度

二、sizeof 詳細用法與陷阱

1. 基礎類型

sizeof(int)        // 4 (典型 32/64 位系統)
sizeof(double)     // 8
sizeof(char)       // 1 (標準保證)

2. 變量與表達式(不求值)


int a = 10;
sizeof(a)          // 4,不讀取 a 的值
sizeof(a + 1.5)    // 8,表達式類型為 double,不計算 a+1.5
sizeof(func())     // func 返回類型大小,func() **不會被調用**

3. 數組與指針——核心陷阱


int arr[10];
sizeof(arr)        // 40 (10 * 4),數組大小
int *p = arr;
sizeof(p)          // 8 (64位指針大小),指針本身大小
sizeof(*p)         // 4,指向的 int 大小

函數參數退化:


void foo(int arr[10]) { // 實際為 int* arr
    sizeof(arr); // 8 (指針大小),非 40!
}

4. 結構體與對齊


struct S { char c; int i; }; // 因對齊通常佔 8 字節
sizeof(struct S) // 8,含填充字節

5. C99 禁止 sizeof 的情況

  • 函數類型本身:sizeof(func) ❌(但 sizeof(func()) ✅)
  • 不完整類型:sizeof(void)、sizeof(外部聲明未定義的結構體)
  • 位域成員:sizeof(s.bitfield) ❌
  • 可變長數組 (VLA) 除外,VLA 的 sizeof 在**運行期**計算。

三、strlen 詳細用法與陷阱

1. 核心原理


size_t strlen(const char *s) {
    size_t len = 0;
    while (*s++) len++;
    return len;
}

依賴 '\0' 結束符,遇到第一個 '\0' 停止。

2. 典型陷阱:缺少 '\0'


char a[] = {'h', 'e', 'l', 'l', 'o'}; // 無 '\0'
strlen(a); // 未定義行為:繼續讀取直到隨機遇到 '\0',結果不可預測
char b[] = "hello"; // 編譯器自動補 '\0',等價於 {'h','e','l','l','o','\0'}
strlen(b); // 5,正確

3. 指針 vs 數組名


char *p = "hello";
strlen(p); // 5
sizeof(p); // 8 (指針大小)

char arr[] = "hello";
strlen(arr); // 5
sizeof(arr); // 6 (含 '\0')

四、實戰對比案例


#include <stdio.h>
#include <string.h>

struct { char c; int i; } s = {'a', 10};
char str[] = "Hello";
char *p = str;

printf("sizeof(s) = %zu\n", sizeof(s));     // 8 (對齊)
printf("sizeof(str) = %zu\n", sizeof(str)); // 6 (含 \0)
printf("strlen(str) = %zu\n", strlen(str)); // 5
printf("sizeof(p) = %zu\n", sizeof(p));     // 8 (指針)
printf("strlen(p) = %zu\n", strlen(p));     // 5

五、總結:決定性判斷流程圖

  1. 需求是「類型/變量佔多少字節」→ sizeof(編譯期常量,可用於陣列大小聲明)。
  2. 需求是「這個字串有多少可見字符」→ strlen(運行期,要求以 '\0' 結尾)。
  3. 面對數組名:sizeof(arr) = 整個數組大小;strlen(arr) = 字串長度(若無 '\0' 會崩潰)。
  4. 面對指針:sizeof(ptr) = 指針大小(4/8);strlen(ptr) = 字串長度。

牢記本質區別,臨場不再混淆。

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