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

C語言指標後置遞增 *(p++) 行為深度解析

     編輯:C 語言問答

核心問題

程式碼片段:

int a[5] = {1,2,3,4,5}, *p;
p = &a[0];
printf("%d", *(p++));

為何輸出 1 而非 2?

運算子優先序與結合性

  • ++(後置)優先序 **高於** *(解參考)。
  • p++ 的**運算結果**是 **遞增前的 `p` 值**(即原本位址),**副作用**是 `p` 指向下一個元素。
  • *(p++) 等價於 *(p舊),先取值再移動指標。

逐步執行模擬

步驟運算式p 值(位址)指向元素運算結果副作用
1初始&a[0]a[0] (值 1)--
2p++&a[0]a[0]&a[0] (舊值)p 變為 &a[1]
3*(p++)--解參考 &a[0] → 1-
4printf&a[1]a[1] (值 2)輸出 1-

追問:`printf("%d,%d", *(p++), *(++p));` 輸出 2,2 原因

**函數引數求值順序在 C 標準中未定義**(Unspecified behavior),編譯器可從右至左、左至右或任意順序計算。

  • 若**從右至左**求值(常見於 x86 cdecl 呼叫慣例):
    1. 先算 `*(++p)`:`p` 從 `&a[0]` → `&a[1]`,解參考得 2。
    2. 再算 `*(p++)`:`p` 現為 `&a[1]`,解參考得 2,然後 `p` → `&a[2]`。
    3. 輸出 `2, 2`。
  • 若從左至右:先 `*(p++)` 得 1,`p`→`&a[1]`;再 `*(++p)`:`p`→`&a[2]`,得 3 → 輸出 `1, 3`。

結論:在同一敘述中對同一變數同時進行讀取與修改(或多次修改),行為**未定義/未指定**,嚴禁在實務程式碼中這樣寫。應拆分為多行明確序列點。

正確改寫範例

// 想印出 a[0], a[1]
printf("%d, %d", *p, *(p+1));  // 不修改 p
// 或
printf("%d", *p); p++;
printf("%d", *p); p++;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved