char *p[] = {"to","yes","is ok","how do you do ?","holle"};
int main() {
int a[5] = {0};
char **t = p;
// 打印原始地址
for(int i=0;i<5;i++) printf("%x\t", p[i]);
// 計算字符串長度 - 錯誤方式
for(int i=0;i<5;i++) {
while(*t[i] != '\0') {
t[i]++; // 錯誤:修改了原數組指針!
a[i]++;
}
}
// 打印長度
for(int i=0;i<5;i++) printf("%d\n", a[i]);
// 打印地址 - 已被改變!
for(int i=0;i<5;i++) printf("%x\t", p[i]);
}
t[i]++ 直接修改了 p 數組中的指針值,導致原字符串起始地址丟失。
執行前: p[0] → "to\0" (地址 0x403000) 執行後: p[0] → "o\0" (地址 0x403001) ← 指針後移!
char *p[] = {"to","yes","is ok","how do you do ?","holle"};
int main() {
int a[5] = {0};
for(int i=0;i<5;i++) printf("%x\t", p[i]);
printf("\n");
for(int i=0;i<5;i++) {
char *t = p[i]; // 關鍵:使用臨時指針副本
while(*t != '\0') {
t++; // 修改副本,不影響原數組
a[i]++;
}
}
for(int i=0;i<5;i++) printf("%d\n", a[i]);
for(int i=0;i<5;i++) printf("%x\t", p[i]); // 地址保持不變
printf("\n");
}
| 操作 | t[i]++ | t++ (t為副本) |
|---|---|---|
| 影響對象 | 原數組 p 中的指針 | 局部變量 t (棧上副本) |
| 原字符串 | 起始地址丟失 | 完全保持不變 |
| 適用場景 | 需要永久修改指針 | 臨時遍歷/計算 |
棧內存: 堆/數據區:
t (局部變量) ──────┐ p[0] ──→ "to\0" (只讀)
│ p[1] ──→ "yes\0"
t = p[0] (複製地址)┘
t++ 只移動局部副本