首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 指針傳參陷阱:函數內修改指針值不影響外部指針地址

     編輯:程式設計綜合問答

代碼還原


int k=7, m=5;
void f(int **s) {
    int *t = &k;
    *s = &t;      // 修改 s 指向的指針值(即 *s)
    *s = &m;      // 再次修改 *s
    printf("%d,%d,%d,", k, *t, **s); // 7,5,5
}
int main() {
    int i=3, *p=&i, **r=&p;
    f(r);
    printf("%d,%d,%d\n", i, *p, **r); // 3,3,3
}

關鍵解析

  • `f(int **s)` 接收的是 **指針變量 `r` 的地址**(即 `**r` 的一級指針地址)。
  • 函數內 `*s = &t` 修改的是 `*r`(即 `p`)的**值**,使 `p` 指向 `t`/`&m`。
  • 但 `r` 本身(二級指針量)的**地址未變**,主函數的 `r` 仍指向 `p`。
  • 函數返回後,`p` 已被改為指向 `m`(值 5),但主函數打印 `i`(3)、`*p`(5)、`**r`(5)?
    實際輸出 `3,3,3` 說明編碼中 `*s = &t` 等操作**未真正生效**或被優化,核心是:**傳遞的是 `r` 的副本(地址值),函數內修改 `*s` 只能影響 `p` 的值,不能改變 `r` 指向 `p` 這一事實**。

通俗類比

房間號 = 地址,房間裡的紙條 = 值。
`r` 存放 `p` 的房間號;`p` 存放 `i` 的房間號。
`f` 拿到 `r` 的房間號,進屋把 `p` 手裡的紙條換成 `m` 的房間號。
但 `r` 手裡的紙條(存 `p` 房間號)沒換,主函數仍按 `r`→`p`→`i` 找到 3。

結論

指針作為參數傳遞,函數可修改指針指向的內容,不可修改調用者的指針變量本身(除非傳指針的指針並修改解引用後的值)。本例中 `f` 修改了 `p` 的指向,但 `r` 仍指向 `p`,最終 `**r` 取決於 `p` 當前指向。

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