int fun(char *s) {
char *p = s;
while (*p != 0) p++;
return p - s;
}
// 調用:fun("0ABCDEF") 返回 7
題主錯誤理解:
char *p = s; → p指向字符'0' (ASCII 48)*p 等於字符'0',而非數值0while(*p != 0) 比較的是字符值與數值0,即'0' != 0 (48 != 0) 為真\0 (數值0) 才停止地址: 0x1000 0x1001 0x1002 0x1003 0x1004 0x1005 0x1006 0x1007
內容: '0' 'A' 'B' 'C' 'D' 'E' 'F' '\0'
↑ ↑
s p (循環結束時)
p - s = 0x1007 - 0x1000 = 7 (指針差值 = 元素個數 = 字符串長度)
| 步驟 | p地址 | *p值 | *p != 0 | 動作 |
|---|---|---|---|---|
| 初始 | 0x1000 | '0'(48) | true | p++ |
| 1 | 0x1001 | 'A'(65) | true | p++ |
| 2 | 0x1002 | 'B'(66) | true | p++ |
| 3 | 0x1003 | 'C'(67) | true | p++ |
| 4 | 0x1004 | 'D'(68) | true | p++ |
| 5 | 0x1005 | 'E'(69) | true | p++ |
| 6 | 0x1006 | 'F'(70) | true | p++ |
| 7 | 0x1007 | '\0'(0) | false | 退出循環 |
ptrdiff_t (有符號整數)p - s = 7 表示p比s向後7個char元素(char*)p - (char*)s / sizeof(char)size_t strlen(const char *s) {
const char *p = s;
while (*p) p++;
return p - s;
}
char a[10], b[10];
char *p1 = a, *p2 = b;
ptrdiff_t diff = p1 - p2; // 未定義行為!
'0' vs 數值0 vs 空指針NULL'0' = 48 (ASCII)
0 = 0 (整數字面量,也用作空指針常量)
'\0' = 0 (字符字面量,字符串結束符)
NULL = (void*)0 (空指針宏)
void reverse(char *s) {
char *p = s;
while (*p) p++; // p 指向 \0
p--; // 指向最後一個字符
while (s < p) {
char tmp = *s;
*s++ = *p;
*p-- = tmp;
}
}
while(*p) 或 while(*p != '\0')p - s 等價於 strlen(s)ptrdiff_t (通常在中定義)這道題考察指針算術、字符串內存佈局、字符與數值區別三大核心知識點。畫內存圖、逐步追蹤是解決此類問題的最有效方法。