指針總結

1 引言

最近在上數據結構課時,老師讓複習一下指針的應用。然後就百度了很多指針的知識,特地彙總了一下。當然本文不是我原創,而上借鑑了很多人的一些總結。在此表示衷心感謝。

2 什麼是指針?

指針就是一種變量類型。它的大小依機器而定,在32位機上一般是4個字節。指針變量中存儲的值是一個內存地址。

2.1 常見指針

分析指針,可以從變量名處起,根據運算符優先級結合,一步一步分析.
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結合,說明該指針所指向的元素是整型數據. 所以P是一個返回指向整型數據的指針的指針。
int p(int); //從P處起,先與()結合,說明P是一個函數,然後進入()裏分析,說明該函數有一個整型變量的參數然後再與外面的int 結合,說明函數的返回值是一個整型數據.所以P是一個有整型參數且返回類型爲整型的函數。
int (*p)(int); //從P處開始,先與指針結合,說明P是一個指針,然後與()結合,說明指針指向的是一個函數,然後再與()裏的int 結合,說明函數有一個int 型的參數,再與最外層的int 結合,說明函數的返回類型是整型,所以P是一個指向有一個整型參數且返回類型爲整型的函數的指針。
int *(*p(int))[3]; //從 P開始,先與()結合,說明P是一個函數,然後進入()裏面,與int結合,說明函數有一個整型變量參數,然後再與外面的結合,說明函數返回的是一個指針,,然後到最外面一層,先與[]結合,說明返回的指針指向的是一個數組,然後再與結合,說明數組裏的元素是指針,然後再與int 結合,說明指針指向的內容是整型數據.所以P是一個參數爲一個整數且返回一個指向由整型指針變量組成的數組的指針變量的函數。

2.2 細說指針

一個指針包括以下4個方面:指針類型、指針指向數據類型、指針指向的內存區、指針在內存中佔空間大小。
例如:int *ptr;
char *ptr;
int **ptr;
int (*ptr)[3];
int *(*ptr)[3];

指針類型: 去掉變量名,所剩就是指針類型,指針類型爲 int *,char*,int **, int (*)[3],int *(*)[3];
指針所指數據類型: 去掉變量名及名字左邊的 *, int,char,int *,int() [3],int*()[3] 即爲指針指向數據的類型;
指針指向的內存區:指針指向數據類型爲多大,那麼指針指向的內存區大小就爲多少。
指針在內存中所佔空間大小:在 32位的系統上, 指針在內存中始終是一個佔了4個字節的數據類型。指針本身佔據的內存這個概念在判斷一個指針表達式是否是左值是很有用。(C/C++中的表達式分爲兩種:1) 左值:可以出現在賦值語句的左邊或右邊。左值表達式指向一個存在於內存中的對象,我們可以對這個對象進行讀寫操作。2) 右值:只能出現在賦值的右邊。右值表達式返回對象進行運算後的值。簡單的說,左值相當於地址值,右值相當於數據值。變量是左值,常量和表達式是右值。
)

2.3 指針的操作

一個指針p加減一個整數N後,結果是一個新指針pnew,兩者的類型相同,只是新指針的值比舊指針的值加減了N*sizeof(p所指向的類型)個字節。
兩個指針不能相加,無意義,非法操作。但是兩個指針可以進行相減,主要應用於數組操作。
&是取地址運算符,*是間接運算符。&a的運算結果是一個指針,指針的類型是a的類型加個*,指針所指向的類型是a的類型。指針所指向的地址就是a的地址。*p的運算結果比較多。

2.4 指針表達式

一個表達式的結果是指針,那麼這個表達式就是指針表達式。一樣具有指針的四要素。

2.5 指針與數組

數組是內存中一段連續的地址空間,數組名錶示這段空間的首地址。可以認爲數組名是一個常量的地址值,因此它是不可以做左值的,但可以做右值。
在算術操作上,數組名與指針有着相似之處,可以做與整數的加減操作,下標操作,解引用操作,但不能做自增自減操作與賦值操作。
數組名不是指針,因爲它不是變量,而是一個常量,其值等於數組首項的地址。在C/C++中我們可以改變一個變量中存儲的值,但不能改變這個變量所在的內存地址。因爲數組名是地址常量,所以我們可以把數組名賦值給同類型的指針,就相當於把一個整數常量賦值給int型變量一樣。
在將數組名當作參數傳遞給函數時,函數需要用一個指針型變量來接收這個參數,此時即使將這個變量寫成指針形式,它代表的也不再是數組,而是一個指針變量了。
將數組名當作sizeof的參數時,返回的是整個數組佔用的內存空間字節數,而將指針當作sizeof(*數組名)的參數時,返回的是指針本身佔用的內存空間數,一般爲4。

2.6 指針類型轉換

當我們初始化一個指針或給一個指針賦值時,賦值號的左邊是一個指針,賦值號的右邊是一個指針表達式,這就要求兩邊的類型一致,所指向的類型也一致,如果不一致的話,需要進行強制類型轉換。語法格式是:(TYPE *)p;
這樣強制類型轉換的結果是一個新指針,該新指針的類型是TYPE *,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。要注意的是,原來的指針p的一切屬性都沒有被修改。
另外,一個函數如果使用了指針作爲形參, 那麼在函數調用語句的實參和形參的結合過程中,也必須保證類型一致 ,否則需要強制轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章