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

char 類型與補碼深度解析:為什麼 strlen 會返回 255?

     編輯:關於C語言

char 類型與補碼深度解析:為什麼 strlen 會返回 255?

一段看似簡單的代碼,輸出卻令人驚訝:

char a[1000];
for (int i = 0; i < 999; i++)
    a[i] = -1 - i;
printf("%d\n", strlen(a)); // 輸出 255,而非 999!

現象還原

  • char 範圍:-128 ~ 127(有符號,視編譯器實現)
  • strlen 遇 \0 (值 0) 停止
  • 迴圈執行 999 次,理應填滿 a[0]~a[998]
  • 實際 strlen(a) == 255

逐步推演:補碼溢出與環繞

i計算 -1-i數學值補碼(8位)無符號解讀a[i] 實際值
0-1-0-111111111255-1
127-1-127-12810000000128-128
128-1-128-1291 01111111 → 01111111127127
129-1-129-1301 01111110 → 01111110126126
..................
255-1-255-2561 00000000 → 0000000000 (\0)

關鍵節點

  1. i = 128:-129 超出 char 下界,高位丟棄,補碼變為 01111111 (127)
  2. i = 128~255:值從 127 遞減至 0
  3. i = 255:a[255] = 0 → 字符串結束標記
  4. a[0]~a[254] 均非 0,strlen 計數 255 後遇 \0 停止

補碼複習:為什麼高位丟棄?

  • 有符號 8 位整數範圍 -128 ~ 127
  • -129 二進制需 9 位:1 01111111
  • char 只有 8 位,截取低 8 位 01111111 = 127
  • 這是溢出環繞,C 標準對有符號溢出屬未定義行為,但兩補碼機器上普遍表現為環繞

避坑指南

  1. 明確 char 符號性:用 signed char / unsigned char 避免實現相關行為
  2. 字符串操作用 unsigned char:避免負值被誤判為結束符
  3. 數值運算勿用 char:用 int 計算,結果再截斷存入 char
  4. 調試技巧:用 %hhd 打印 char 有符號值,%hhu 打印無符號值

延伸:為什麼 C 標準不固定 char 符號?

歷史原因:早期架構(如 ARM 預設 unsigned、x86 預設 signed)選擇不同,標準委會為了性能不強制統一。現代代碼永不假設 char 符號,需顯式指定。

這個例子生動展示了「類型範圍、補碼環繞、字符串結束符」三大概念的交互碰撞,是 C 語言底層特性的經典教學案例。

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