天天看點

C++自定義資料類型之指針

      好像這方面的知識了解起來很費勁兒,看了三四遍了吧,還是模模糊糊的,沒有條理性,是以就開始翻看部落格裡這方面的内容,可能是看的少吧,還是不能讓我徹底的明白,是以就度娘了一下,看了幾篇關于指針的文章,覺得有必要去仔細的推敲。

       要了解指針,多多少少會出現一些比較複雜的類型,是以先介紹一下如何完全了解一個複雜類型,要了解複雜類型其實很簡單,一個類型裡會出現很多運算符,他們也像普通的表式一樣,有優先級,其優先級和運算優先級一樣,是以我總結了一下其原則: 從變量名處起,根運算符優先級結合,一步一步分析.下面讓我們先從簡單的類型開始慢慢分析吧:

        int p;              ///這是一個普通的整型變量

        int *p;            ///首先從P處開始,先與*結合,是以說明P是一個指針,然後再與int結合,說明指針所指向的内容的類型為int型.是以P是一個傳回整型資料的指針

        int p[3];          ///首先從P處開始,先與[]結合,說明P是一個數組,然後與int結合,說明組裡的元素是整型的,是以P是一個由整型資料組成的數組

        int *p[3];         ///首先從P處開始,先與[]結合,因為其優先級比*高,是以P是一個數組,然後再與*結合,說明數組裡的元素是指針類型,然後再與int結合,說明指針所指向的内容的類型是整型的,是以P是一個由傳回整型資料的指針所組成的數組

        int (*p)[3];      ///首先從P處開始,先與*結合,說明P是一個指針然後再與[]結(與"( )"這步可以忽略,隻是為了改變優先級),說明指針所指向的内容是一個數組,然後再與int結合,說明數組裡的元素是整型的.是以P是一個指向由整型資料組成的數組的指針

        int **p;           ///首先從P開始,先與*結合,說是P是一個指針,然後再與*結合,說明指針所指向的元素是指針,然後再與int結合,說明該指針所指向的元素是整型資料.由于二級指針以及更進階的指針極少用在複雜的類型中,是以後面更複雜的類型我們就不考慮多級指針了,最多隻考慮一級指針

        int p(int);       ///從P處起,先與( )結合,說明P是一個函數,然後進入( )裡分析,說明該函數有一個整型變量的參數然後再與外面的int結合,說明函數的傳回值是一個整型資料

        Int (*p)(int);      ///從P處開始,先與指針結合,說明P是一個指針,然後與()結合,說明指針指向的是一個函數,然後再與( )裡的int結合,說明函數有一個int型的參數,再與最外層的int結合,說明函數的傳回類型是整型,是以P是一個指向有一個整型參數且傳回類型為整型的函數的指針

        int *(*p(int))[3];    ///從P開始,先與( )結合,說明P是一個函數,然後進入( )裡面,與int結合,說明函數有一個整型變量參數,然後再與外面的*結合,說明函數傳回的是一個指針,,然後到最外面一層,先與[]結合,說明傳回的指針指向的是一個數組,然後再與*結合,說明數組裡的元素是指針,然後再與int結合,說明指針指向的内容是整型資料.是以P是一個參數為一個整資料且傳回一個指向由整型指針變量組成的數組的指針變量的函數.

        指針是一個特殊的變量,它裡面存儲的數值被解釋成為記憶體裡的一個位址。要搞清一個指針需要搞清指針的四方面的内容:指針的類型、指針所指向的類型、指針的值或叫指針所指向的記憶體區、指針本身所占據的記憶體區。

       先聲明幾個指針放着做例子:

       (1)int*ptr; 

       (2)char*ptr; 

       (3)int**ptr; 

       (4)int(*ptr)[3]; 

       (5)int*(*ptr)[4]; 

       1.指針的類型

       從文法的角度看,你隻要把指針聲明語句裡的指針名字去掉,剩下的部分就是這個指針的類型。這是指針本身所具有的類型。讓我們看看例一中各個指針的類型:

        (1)int*ptr;                ///指針的類型是int* 

        (2)char*ptr;           ///指針的類型是char* 

        (3)int**ptr;             ///指針的類型是int** 

        (4)int(*ptr)[3];         ///指針的類型是int(*)[3] 

        (5)int*(*ptr)[4];       ///指針的類型是int*(*)[4] 

        2.指針所指向的類型當你通過指針來通路指針所指向的記憶體區時,指針所指向的類型決定了編譯器将把那片記憶體區裡的内容當做什麼來看待。從文法上看,你隻須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。

例如:

       (1)int*ptr;            ///指針所指向的類型是int 

       (2)char*ptr;           ///指針所指向的的類型是char 

       (3)int**ptr;             ///指針所指向的的類型是int* 

       (4)int(*ptr)[3];           ///指針所指向的的類型是int( )[3]

       (5)int*(*ptr)[4];          ///指針所指向的的類型是int*( )[4] 

       在指針的算術運算中,指針所指向的類型有很大的作用。指針的類型(即指針本身的類型)和指針所指向的類型是兩個概念。當你對C越來越熟悉時,你會發現,把與指針攪和在一起的"類型"這個概念分成"指針的類型"和"指針所指向的類型"兩個概念,是精通指針的關鍵點之一。我看了不少書,發現有些寫得差的書中,就把指針的這兩個概念攪在一起了,是以看起書來前後沖突,越看越糊塗。

        3.指針的值----或者叫指針所指向的記憶體區或位址指針的值是指針本身存儲的數值,這個值将被編譯器當作一個位址,而不是一個一般的數值。在32位程式裡,所有類型的值都是一個32位整數,因為32位程式裡記憶體位址全都是32位長。指針所指向的記憶體區就是從指針的值所代表的那個記憶體位址開始,長度為sizeof(指針所指向的類型)的一區以後,我們說一個指針的值是XX,就相當于說該指針指向了以XX為首位址的一片記憶體區域;我們說一個指針指向了某塊記憶體區域,就相當于說該指針的值是這塊記憶體區域的首位址。指針所指向的記憶體區和指針所指向的類型是兩個完全不同的概念。在例一中,指針所指向的類型已經有了,但由于指針還未初始化,是以它所指向的記憶體區是不存的,或者說是無意義的。以後,每遇到一個指針,都應該問問:這個指針的類型是什麼?指針指的類型是什麼?該指針指向了哪裡?(重點注意)

        4指針本身所占據的記憶體區指針本身占了多大的記憶體?你隻要用函數sizeof(指針的類型)測一下就知道了。在32位平台裡,指針本身占據了4個位元組的長度。

         指針本身占據的記憶體這個概念在判斷一個指針表達式(後面會解釋)是否是左值

時很有用。