程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言雜談(二)自增運算符++與間接訪問運算符*的結合關系和應用模式,雜談運算符

C語言雜談(二)自增運算符++與間接訪問運算符*的結合關系和應用模式,雜談運算符

編輯:關於C語言

C語言雜談(二)自增運算符++與間接訪問運算符*的結合關系和應用模式,雜談運算符


自增運算符++有前綴和後綴兩種,在搭配間接訪問運算符*時,因為順序、括號和結合關系的影響,很容易讓人產生誤解,產生錯誤的結果,這篇文章來詳細分析一下這幾種運算符的不同搭配情況。

++、--和*的優先級順序

在C語言運算符的優先級順序中,後綴的++和--運算符運算優先級16,結合關系是從左到右;簡介訪問運算符*、前綴++和--運算符運算優先級15,結合關系是從右到左。根據這個關系,可以分析出不同情況下的應用。為了更直觀的體現,有以下的例子。

舉例說明

有數組a[5],值分別為10,11,12,13,14;有指針p指向a[0];另有指針q和整數b。這裡注意的是,每段代碼開始前,a數組的值和p指針都會回復初始狀態。(在一開始寫這些測試代碼時,忽視了回復初值的問題,導致很多奇怪的錯誤,比如p已經不再指向a[0],或者a[0]本身已經改變了。)

1.後綴++

p = a;
q = p++;

p指向a[1]值為11,q指向a[0]值為10。說明後綴自增運算符,返回的是自增前的值。

2.前綴++

p = a;
q = ++p;

p指向a[1]值為11,q指向a[1]值為11。說明前綴自增運算符,返回的是自增後的值。

3.*p++

p = a;
b = *p++;

p指向11,b值為10。此時先執行p++,p自增,指向a[1]。p++的值為自增前的值,即a[0]的地址,a[0]的值賦給b。

4.*(p++)

p = a;
b = *(p++);

結果與3相同。*與++運算符優先級相同,運算順序是自右向左。

5.(*p)++

p = a;
b = (*p)++;

此時雖然結果與3相同,但這時是先取p指向的值即a[0],a[0]自增即a[0]的值變成11,自增是後綴的,返回自增前的值,即10。結果相同,但原理還有很大的差別。

6. *++p

p = a;
b = *++p;

p指向11,b值為11。先執行++p,p自增,指向a[1],++p的值為自增後的值,即a[1]的地址,a[1]的值賦給b。

7.*(++p)

p = a;
b = *(++p);

與6結果相同,*與++運算符優先級相同,運算順序是自右向左。

8.++(*p)

p = a;
b = ++(*p);

p指向11,b值為11,先取p指向a[0]值為10,a[0]的值自增變成11,前綴自增返回值為11賦給b。

9. ++*p

p = a;
b = ++*p;

結果同8,*與++運算符優先級相同,運算順序是自右向左。

總結

第一個原則就是前綴值為變化後,後綴值為變化前。第二個原則,*++優先級相同,讀的時候從右向左。這些都是本人自己試著總結的,如有錯誤請多指正,希望對有疑惑的朋友有所幫助。

完整代碼

/*本程序用來測試前綴自增運算符,後綴自增運算符,取內容符號的運算優先級以及順序帶來的返回值的影響*/

#include "stdio.h"

void myPrint(int n,int j, int k)
{
    printf("no.%d:p->%d, q->%d\n", n,j, k);
}
void myPrintNew(int n,int j, int k)
{
    printf("no.%d:p->%d, b->%d\n", n,j, k);
}
void init(int a[5])
{
    a[0] = 10;
    a[1] = 11;
    a[2] = 12;
    a[3] = 13;
    a[4] = 14;
}//防止某些測試的操作改變了數組的值,在每次使用數組之前使用初始化函數


int main(int argc, char* argv)
{
    //int a[5] = { 10, 11, 12, 13, 14 }, *p,*q,b;
    int a[5] ,*p, *q, b;
    init(a);

    //1.
    init(a);
    p = a;
    q = p++;
    myPrint(1,*p, *q);
    //p指向11,q指向10
    //後綴自增運算符,返回的是自增前的值

    //2.
    init(a);
    p = a;
    q = ++p;
    myPrint(2,*p, *q);
    //p指向11,q指向11
    //前綴自增運算符,返回的是自增後的值
    //1,2:閱讀順序:從左到右

    //3.
    init(a);
    p = a;
    b = *p++;
    myPrintNew(3,*p, b);
    //p指向11,b值為10
    //先執行p++,p自增,指向a[1],p++的值為自增前的值(見1),即a[0]的地址,a[0]的值賦給b

    //4.
    init(a);
    p = a;
    b = *(p++);
    myPrintNew(4,*p, b);
    //結果與3相同
    //*與++運算符優先級相同,運算順序是自右向左

    //5.
    init(a);
    p = a;
    b = (*p)++;
    myPrintNew(5,*p, b);
    //結果與3相同,但這時是先取p指向的值即a[0],a[0]自增即a[0]的值變成11,自增是後綴的,返回自增前的值,即10
    //與8對照

    //6。
    init(a);
    p = a;
    b = *++p;
    myPrintNew(6, *p, b);
    //p指向11,b值為11
    //先執行++p,p自增,指向a[1],++p的值為自增後的值(見2),即a[1]的地址,a[1]的值賦給b

    //7.
    init(a);
    p = a;
    b = *(++p);
    myPrintNew(7, *p, b);
    //與6結果相同
    //*與++運算符優先級相同,運算順序是自右向左

    //8
    init(a);
    p = a;
    b = ++(*p);
    myPrintNew(8, *p, b);
    //p指向11,b值為11
    //先取p指向a[0]值為10,a[0]的值自增變成11,前綴自增返回值為11賦給b
    
    //9??
    init(a);
    p = a;
    b = ++*p;
    myPrintNew(9, *p, b);
    //結果同8
    //*與++運算符優先級相同,運算順序是自右向左

    return 0;
}

運行結果

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved