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

C語言指針與自增運算符結合的6種運算順序完全圖解

     編輯:關於C語言

C語言指針與自增運算符結合的6種運算順序完全圖解

指針解引用*與自增++/自減--組合時,優先級與結合性極易混淆。本文通過代碼實測,徹底釐清6種組合的求值順序與副作用差異。

一、測試代碼與輸出

#include <stdio.h>
int main() {
    int a[3] = {1,3,5};
    int *p, i;

    // 1. *p++
    p = a; printf("-----1: *p++ -----\n");
    printf("return: %d, *p after: %d\n", *p++, *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    // 2. (*p)++
    p = a; printf("-----2: (*p)++ -----\n");
    printf("return: %d, *p after: %d\n", (*p)++, *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    // 3. *(p++)
    p = a; printf("-----3: *(p++) -----\n");
    printf("return: %d, *p after: %d\n", *(p++), *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    // 4. ++*p
    p = a; printf("-----4: ++*p -----\n");
    printf("return: %d, *p after: %d\n", ++*p, *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    // 5. ++(*p)
    p = a; a[0]=1; printf("-----5: ++(*p) -----\n");
    printf("return: %d, *p after: %d\n", ++(*p), *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    // 6. *(++p)
    p = a; a[0]=1; printf("-----6: *(++p) -----\n");
    printf("return: %d, *p after: %d\n", *(++p), *p);
    for(i=0;i<3;i++) printf("%d ", a[i]); puts("");

    return 0;
}

輸出結果:

-----1: *p++ -----
return: 1, *p after: 3
1 3 5
-----2: (*p)++ -----
return: 1, *p after: 2
2 3 5
-----3: *(p++) -----
return: 1, *p after: 3
1 3 5
-----4: ++*p -----
return: 2, *p after: 2
2 3 5
-----5: ++(*p) -----
return: 2, *p after: 2
2 3 5
-----6: *(++p) -----
return: 3, *p after: 3
1 3 5

二、逐組深度解析

表達式運算順序返回值副作用等價寫法
*p++①取*p值 ②p++舊*p值指針後移*(p++)
(*p)++①取*p值 ②*p值++舊*p值所指對象值+1—
*(p++)①取*p值 ②p++舊*p值指針後移*p++
++*p①*p值++ ②取新*p值新*p值所指對象值+1++(*p)
++(*p)①*p值++ ②取新*p值新*p值所指對象值+1++*p
*(++p)①p++ ②取新*p值新位置的值指針後移*++p

三、核心規律總結

  1. 後綴(p++、(*p)++):先取值,後副作用。返回舊值。
  2. 前綴(++*p、++p):先副作用,後取值。返回新值。
  3. 括號改變綁定對象:
    • *p++ ≡ *(p++):++綁定p(指針移動)。
    • (*p)++:++綁定*p(對象值修改)。
    • ++*p ≡ ++(*p):++綁定*p(對象值修改)。
    • *(++p):++綁定p(指針移動)。

四、避坑最佳實踐

  • 原則:單一語句只做一件事。拆分為獨立步驟:
// 易讀、無歧義
int val = *p;
p++;
// 或
(*p)++;
// 或
p++;
int val = *p;
  • 若必須組合,加括號明確意圖:(*p)++、*(p++)、++(*p)、*(++p)。
  • 代碼審查時,標記所有指針+自增組合為高風險,要求重構。

理解運算符優先級(++/-- > *(解引用)> *(乘法))與結合性,配合括號顯式分組,是寫出無歧義指針代碼的鑰匙。

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