c/c++中的指標通常來說有兩個屬性:
1. 指向變數
2. 指向物件的位址和長度
指標其實就是儲存被指向變數的位址,並不儲存其長度;
而且存的這個位址僅是變數的首位址,並不是該變數佔據記憶體的所有位址空間。如:
目前大多數的c/c++編譯環境中,整型int資料佔4個位元組的空間,如上圖所示。所以指標p儲存的位址(即指向的位址)為1號記憶體單元(首位址)。
當需要讀取乙個例如int型資料時,編譯器根據指標的型別從指標指向的位址開始向後定址。指標型別不同則定址範圍也不同,比如:
int*從指定位址向後尋找4位元組作為變數的儲存單元;
double*從指定位址向後尋找8位元組作為變數的儲存單元。
如果我們從指標實現的角度講,指標就是乙個整型變數,它儲存的是乙個位址值,沒有任何附加資訊。目前為止貌似沒有什麼問題,其實不然。
就拿上述的**:如果用乙個整型變數b儲存a的位址,即int b=&a。當對b加1時,得到的新的位址相當於對a的首位址加1,即&a+1,由於int佔連續的四個儲存單元(預設),此時b儲存的是第二塊儲存單元的位址,所以根據變數b儲存的位址,將無法完整的讀出變數a的值,導致錯誤。而通過指標變數,可以解決這類問題:如果對上述**中的指標p加1的話,實際上是p+sizeof(int),一次性增加了4個儲存單元。
ps.指標本身所佔據的記憶體區 :
指標本身佔了多大的記憶體?你只要用函式sizeof(指標的型別)測一下就知道了。
指標的作用是用來對記憶體空間進行定址,在32位機上,所有指標型別變數占用記憶體位元組數都為4,因為32位機是按32位定址的。如果在64位機上,指標占用記憶體大小就是:8個位元組。
void *vp;
void*是一種特別的指標,因為它沒有指向的型別,或者說不能根據這個型別判斷出指向物件的長度。void *指標具有以下特點:
任何指標(包括函式指標)都可以賦值給void指標;
type *p;
vp=p;
//不需轉換
//只獲得變數/物件位址而不獲得大小
2. void指標賦值給其他型別的指標時都要進行轉換;
type * p=(type *)vp;
//轉換型別也就是獲得指向變數/物件大小
3. void指標在強制轉換成具體型別前,不能解引用;
*vp
//錯誤
//因為void指標只知道,指向變數/物件的起始位址
//而不知道指向變數/物件的大小(佔幾個位元組)所以無法正確引用
4. void指標不能參與指標運算,除非進行轉換。
(type*)vp++;
//等價於:vp=vp+sizeof(type)
void*的作用
傳參:通用型別
可以作為函式模板,鍊錶等引數的通用引數。在使用時,只需要強制型別轉換就可以。
例如記憶體操作函式memcpy和memset的函式原型分別為:
void* memcpy(void *dest, constvoid *src, size_t len);
void* memset(void *buffer, int c, size_t num);
這樣,任何型別的指標都可以傳入memcpy和memset中,這也真實地體現了記憶體操作函式的意義,因為它操作的物件僅僅是一片記憶體,而不論這片記憶體是什麼型別。
強制型別轉換
有時候由於過載等的干擾,導致需要轉換成void *,來進行取位址。
例如,(void *)obj.member,就可以取到member的位址;直接&(obj.member)取到的實際上是obj的開始位址。
指向0的位址
(void *)0,指向全是0的位址,相當於null。
下面舉乙個使用void*指標的demo:
#include
#include
using
namespace
std;
typedef
struct tag_st
st;int main()
注:關於void*指標的介紹,參考於wangicter的部落格wangicter的專欄。 無型別與無型別指標
無型別,又為抽象型別 沒有對應的實體,不能直接定義變數,但可以定義指標。1 失去指標指向的功能 2 p指標此時不具有 1的能力。在gcc編譯器下,無型別指標課加1。void 是一種特別的指標,因為它沒有指向的型別,或者說不能根據這個型別判斷出指向物件的長度。void 指標具有以下特點 1.任何指標 ...
指向void型別的指標
指向void的指標是個非常有趣的東西,乙個指向任何物件型別的指標都可以賦值給型別為void 的變數,void 可以賦值給另乙個void 兩個void 可以比較是否相等 當兩個指標比較時,是看它們是否指向同一塊記憶體位址 而且可以顯示的將void 轉換到另乙個型別。初次之外,其他任何對void 的操作...
void指標的使用
整理網路資源 在 c語言中在任何時候都可以用 void 型別的指標來代替其他型別的指標,void 指標可以指向任何資料型別的變數 如果要通過 void 指標去獲取它所指向的變數值時候,需要先將 void 指標強制型別轉換成和變數名型別想匹配的資料型別指標後再進行操作 指標的強類型別轉化 void p...