天天看點

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、細說指針

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

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

(1)int*ptr; (2)char*ptr; (3)int**ptr;

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

1.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]

1.2指針所指向的類型

當你通過指針來通路指針所指向的記憶體區時,指針所指向的類型決定了編譯器将把那片記憶體區裡的内容當做什麼來看待。

從文法上看,你隻須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。例如:

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

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

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

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

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

1.3指針的值–或者叫指針所指向的記憶體區或位址

指針的值是指針本身存儲的數值,這個值将被編譯器當作一個位址,而不是一個一般的數值。在32位程式裡,所有類型的指針的值都是一個32位整數,因為32位程式裡記憶體位址全都是32位長。 指針所指向的記憶體區就是從指針的值所代表的那個記憶體位址開始,長度為sizeof(指針所指向的類型)的一片記憶體區。以後,我們說一個指針的值是XX,就相當于說該指針指向了以XX為首位址的一片記憶體區域;我們說一個指針指向了某塊記憶體區域,就相當于說該指針的值是這塊記憶體區域的首位址。

指針所指向的記憶體區和指針所指向的類型是兩個完全不同的概念。在例一中,指針所指向的類型已經有了,但由于指針還未初始化,是以它所指向的記憶體區是不存在的,或者說是無意義的。

1.4指針本身所占據的記憶體區

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

指針本身占據的記憶體這個概念在判斷一個指針表達式是否是左值時很有用。

左值 簡單點說就是可以放在指派運算符左邊的表達式.下面讓我們來看看他的定義: 如果一個表達式可以引用到某一個對象,并且這個對象是一塊記憶體空間且可以被檢查和存儲,那麼這個表達式就可以做為一個左值.當然,有左值當然就會有右值這個概念: 右值指的是引用了一個存儲在某個記憶體位址裡的資料。一個變量可以同時是左值,同時也是右值,兩者不是對立的。

繼續閱讀