const char *cp = "steven";
while (*cp) {
putchar(*cp); // 或 cout << *cp;
++cp;
}
"steven" 類型為 const char[7](含隱式 \0),退化為 const char* 指向首字符 's'。*cp 解引用獲取當前字符。字符值為 0(\0)時為假,終止循環;非 0 為真,繼續。++cp 使指針指向下一字符(char 佔 1 字節,遞增 1 字節)。const char* 承諾不修改字符串內容,字面量存儲於只讀段,寫入導致未定義行為。
const char *cp = "steven";
for (size_t i = 0; cp[i]; ++i) {
putchar(cp[i]);
}
指針版本更接近機器指令(自增 + 間接訪問),無索引計算開銷,是 C 風格字符串處理的慣用模式。
strlen、strcpy、puts 等函數內部均採用類似指針遍歷:
// strlen 簡化版
size_t strlen(const char *s) {
const char *p = s;
while (*p) ++p;
return p - s; // 指針相減得元素個數
}
// puts 簡化版
int puts(const char *s) {
while (*s) putchar(*s++);
putchar('\n');
return 0;
}
p + i 等價 &p[i])。ptrdiff_t(元素個數差)。p[-1]、p[n] 除單純計算地址外不得解引用)。
// C++11 範圍 for
for (char c : "steven") {
if (c) putchar(c); // 仍需檢查 \0
}
// string_view (C++17)
std::string_view sv("steven");
for (char c : sv) putchar(c); // 自動處理長度,無 \0 問題
while (*cp) { ... ++cp; } 是 C 語言處理以空字符結尾字符串的**標準慣用語**。它體現了指針算術的精髓:地址即迭代器,空字符即哨兵。掌握此模式,可讀懂標準庫源碼、寫出高效字符串處理代碼、理解 C 風格字符串的零開銷抽象本質。