日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

彻底攻克C语言指针

發布時間:2023/12/9 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 彻底攻克C语言指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面我們講解了指針數組、二維數組指針、函數指針等幾種較為復雜的指針,它們的定義形式分別是:

  • int?*p1[6];?//指針數組
  • int?*(p2[6]);?//指針數組,和上面的形式等價
  • int?(*p3)[6];?//二維數組指針
  • int?(*p4)(int,?int);?//函數指針
  • 我相信大部分初學者對上面幾種形式的指針都非常迷惑,不知道該從哪里入手去理解,為什么 p1、p2 是數組,而 p3 卻是指針呢,它們僅僅是一個括號的區別。

    指針是C語言中最強大最靈活的一部分,也是最難以理解的一部分,它是學習C語言的重點,沒有學會指針就無從談學會C語言。如果大家覺得上面幾種形式的指針還能勉強接受,那么下面兩個指針是不是讓人抓狂呢?

  • char?*(*?c[10])(int?**p);
  • int?(*(*(*pfunc)(int?*))[5])(int?*);
  • 只要找到了竅門,再復雜的指針也是可以理解的,這節我們就來戳破這層窗戶紙!

    C語言標準規定,對于一個符號的定義,編譯器總是從它的名字開始讀取,然后按照優先級順序依次解析。對,從名字開始,不是從開頭也不是從末尾,這是理解復雜指針的關鍵!

    對于初學者,有幾種運算符的優先級非常容易混淆,它們的優先級從高到低依次是:

    • 定義中被括號( )括起來的那部分。
    • 后綴操作符:括號( )表示這是一個函數,方括號[ ]表示這是一個數組。
    • 前綴操作符:星號*表示“指向xxx的指針”。


    學會了“絕殺招式”,接下來我們就由淺入深,逐個擊破上面的指針定義。

    1)?int *p1[6];

    從 p1 開始理解,它的左邊是 *,右邊是 [ ],[ ] 的優先級高于 *,所以編譯器先解析p1[6],p1 首先是一個擁有 6 個元素的數組,然后再解析int *,它用來說明數組元素的類型。從整體上講,p1 是一個擁有 6 個 int * 元素的數組,也即指針數組。

    2)?int (*p3)[6];

    從 p3 開始理解,( ) 的優先級最高,編譯器先解析(*p3),p3 首先是一個指針,剩下的int [6]是 p3 指向的數據的類型,它是一個擁有 6 個元素的一維數組。從整體上講,p3 是一個指向擁有 6 個 int 元素數組的指針,也即二維數組指針。

    為了能夠通過指針來遍歷數組元素,在定義數組指針時需要進行降維處理,例如三維數組指針實際指向的數據類型是二維數組,二維數組指針實際指向的數據類型是一維數組,一維數組指針實際指向的是一個基本類型;在表達式中,數組名也會進行同樣的轉換(下降一維)。

    3) int (*p4)(int, int);

    從 p4 開始理解,( ) 的優先級最高,編譯器先解析(*p4),p4 首先是一個指針,它后邊的 ( ) 說明 p4 指向的是一個函數,括號中的int, int是參數列表,開頭的int用來說明函數的返回值類型。整體來看,p4 是一個指向原型為int func(int, int);的函數的指針。

    4) char *(* c[10])(int **p);

    這個定義有兩個名字,分別是 c 和 p,乍看起來 p 是指針變量的名字,不過很遺憾這是錯誤的。如果 p 是指針變量名,c[10]這種寫法就又定義了一個新的名字,這讓人匪夷所思。

    以 c 作為變量的名字,先來看括號內部(綠色粗體):

    char *?(* c[10])?(int **p);

    [ ] 的優先級高于 *,編譯器先解析c[10],c 首先是一個數組,它前面的*表明每個數組元素都是一個指針,只是還不知道指向什么類型的數據。整體上來看,(* c[10])說明 c 是一個指針數組,只是指針指向的數據類型尚未確定。

    跳出括號,根據優先級規則(() 的優先級高于 *)應該先看右邊(紅色粗體):

    char *?(* c[10])?(int **p);

    ( )說明是一個函數,int **p是函數參數。

    再看左邊(橘黃色粗體):

    char *?(* c[10])?(int **p);

    char *是函數的返回值類型。

    從整體上看,我們可以將定義分成兩部分:

    char *?(* c[10])?(int **p);

    綠色粗體表明 c 是一個指針數組,紅色粗體表明指針指向的數據類型,合起來就是:c 是一個擁有 10 個元素的指針數組,每個指針指向一個原型為char *func(int **p);的函數。

    5) int (*(*(*pfunc)(int *))[5])(int *);

    從 pfunc 開始理解,先看括號內部(綠色粗體):

    int (*(*(*pfunc)(int *))[5])(int *);

    pfunc 是一個指針。

    跳出括號,看它的兩邊(紅色粗體):

    int (*(*(*pfunc)(int *))[5])(int *);

    根據優先級規則應該先看右邊的(int *),它表明這是一個函數,int *是參數列表。再看左邊的*,它表明函數的返回值是一個指針,只是指針指向的數據類型尚未確定。

    將上面的兩部分合成一個整體,如下面的藍色粗體所示,它表明 pfunc 是一個指向函數的指針,現在函數的參數列表確定了,也知道返回值是一個指針了(只是不知道它指向什么類型的數據)。

    int (*?(*(*pfunc)(int *))?[5])(int *);

    藍色粗體以外的部分,就用來說明函數返回什么類型的指針。

    我們接著分析,再向外跳一層括號(紅色粗體):

    int (*?(*(*pfunc)(int *))?[5])(int *);

    [ ] 的優先級高于 *,先看右邊,[5] 表示這是一個數組,再看左邊,* 表示數組的每個元素都是指針。也就是說,* [5] 是一個指針數組,函數返回的指針就指向這樣一個數組。

    那么,指針數組中的指針又指向什么類型的數據呢?再向外跳一層括號(橘黃色粗體):

    int?(*?(*(*pfunc)(int *))?[5])?(int *);

    先看橘黃色部分的右邊,它是一個函數,再看左邊,它是函數的返回值類型。也就是說,指針數組中的指針指向原型為int func(int *);的函數。

    將上面的三部分合起來就是:pfunc 是一個函數指針(藍色部分),該函數的返回值是一個指針,它指向一個指針數組(紅色部分),指針數組中的指針指向原型為int func(int *);的函數(橘黃色部分)。

    轉載于:https://www.cnblogs.com/ZYDZ/p/9496080.html

    總結

    以上是生活随笔為你收集整理的彻底攻克C语言指针的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。