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

C 語言基本型別範圍陷阱:char 有號無號導致的 strlen 驚魂記

     編輯:關於C語言

現象重現

[c]
#include 
#include 

int main() {
    char arr[1000];
    int i;
    for (i = 0; i < 1000; i++) {
        arr[i] = -1 - i; // 關鍵:賦負值給 char
    }
    printf("%d\n", strlen(arr)); // 輸出 255 (而非 999 或 1000)
    return 0;
}

為什麼是 255?

  1. char 預設有號性由實現定義:x86 GCC/MSVC 預設 signed char (範圍 -128~127)。
  2. 補碼表示:-1 = 0xFF, -2 = 0xFE, ..., -128 = 0x80。
  3. 溢位環繞:i=127 → arr[127]=-128 (0x80);i=128 → -129 需 9 位,截斷為 0x7F (+127);i=255 → -256 截斷為 0x00 (\0)。
  4. strlen 遇 \0 即停止:arr[255] 首個為 0,故長度 255。

記憶體內容演變表

i計算值補碼 (hex)有號解讀備註
0-10xFF-1
127-1280x80-128最小負數
128-1290x7F+127溢位,符號翻轉
255-2560x000首個 \0,strlen 停這裡
256-2570xFF-1循環重複

避坑指南

  1. 明確指定有號性:用 signed char / unsigned char / uint8_t (需 <stdint.h>) 替代裸 char 做數值運算。
  2. 字串緩衝區用 unsigned char 或 uint8_t:避免負值被誤判為結束符。
  3. 位運算、網路協議、二進制解析:一律用無號型別。
  4. 編譯器選項:GCC -funsigned-char / MSVC /J 可強制 char 為無號,但**不建議依賴此選項**,源碼應自說明。

延伸:strlen vs sizeof

[c]
char buf[1000] = "hello";
printf("strlen=%zu, sizeof=%zu\n", strlen(buf), sizeof(buf)); // 5 vs 1000
  • sizeof:編譯期常數,陣列總位元組數。
  • strlen:執行期掃描首個 \0,不含結束符。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved