指針是一個很神奇的變量,在我看來,以指針為基礎,可以延伸出三個值。
1 指針的地址
2 指針的值
3 指針指向的值
有的人或許認為指針指向的值其實和指針本身並不是直接相關連的。
但是其實這個特性確實我們在編程中經常使用的,所以我就把他加了進來。
在介紹之前,如果您對這里已經足夠了解並且有興趣看看我說了什么,那么請跳過這一段~
什么是指針的地址?
指針的也是一個變量,在三十二位計算機中,指針占有四個字節的內存空間,正好可以指滿32位機中左右的內存單元。
所以,很自然的,指針也有一個屬於自己的地址。
如果你定義一個指針,比如這樣:
int *ip;//int pointer
那么獲取其地址的方式就是將ip視為一個普通變量,然后用取地址符獲取其地址:
cout<<&p<<endl;
這樣就在屏幕中打印出了這個指針變量在內存單元中的地址。
這個地址在該進程的生命周期中是不會改變的,因為指針本身只是一個常規變量。
什么是指針的值呢?
之前已經說了,指針是一個變量,是變量,都會存貯一個值。
那么如何查看一個指針的值呢?
我們可以這樣理解一下。
用上面已經定義的ip為例。
假設我已經定義了另一個變量:int temp;
使指針ip指向temp的表達式如下:
ip=&temp;
我們都知道&temp獲取的是temp的地址,那么從表達式就可以知道,其實,ip本身,就表示temp的地址,也就是ip的值。
所以,直接輸出就可以了
cout<<ip<<endl;
最后一個,也是用的比較多的,就是指針指向的值。
為了方便,還是用上面的ip和temp。
ip指向temp,那么獲取temp的值,就可以通過ip中存儲的地址值來獲取temp的值。
如果你學過匯編,那么這是一個很簡單的工作。
而在C語言中,這一過程將更加簡單,只要在指針前加一個'*'號,問題就輕松解決。
也就是說*p可以當成temp用。
當然,指針的用途不僅僅局限於此,指針還可以用於函數間數據的共享處理,以及開辟新的內存單元,調用函數,直接從某一出地址開始執行程序。
至於引用,我只能說C++中的引用就是一個只讀的指針,在參數傳遞的時候編譯器很聰明的做了一些讓開發者省力氣的工作,別的,我還真沒發現什么。
而至於講delete,就必須要講到new。
C++中的new的作用相當C中的malloc,顧名思義,即memory allcoc。
new用於內存分配和布局,功能強大,而且比malloc要簡練不少。
還是上面的那個指針,就可以通過這種方式為其開辟一小塊內存單元:
ip=new int;//如果是數組的話,加上[N]
這樣ip就獲取了一塊大小為int的內存單元。
如何清理呢?
這時就用到了delete。
操作也很簡單,只要將需要釋放的內存單元的指針放在delete后面就可以了
delete ip;
似乎到這里工作就已經結束了,但是昨天的一個隊列清除的函數讓我有了一個想法,而這個想法和delete有很大的關系。
如果我想要清除一個隊列,能不能只用隊列的頭指針呢?
如果delete只是返回一個記錄,將相應的內存空間返還給Os,而不修改其值的話,那么這種想法將是可能的。
所以我做了這樣的嘗試:
int *p=new int; int t=10; p=t; cout<<&p<<endl <<*p<<endl <<p<<endl; delete p; cout<<&p<<endl <<*p<<endl <<p<<endl
輸出結果截圖所示:
在這里可以發現,在經過delete之后,盡管指針的只沒有變,但是指向的內存空間的值已經跑飛了……
在結構體代碼測試的時候,也是如此。
代碼是這樣的:
1 struct Ntemp *temp1=newNtemp;//struct Ntemp{int a;struct Ntemp *next;};
2 temp1->a=320; 3 temp1->next=new Ntemp;//the value of next is changed 4 cout<<(int *)temp1<<endl; 5 cout<<temp1->next<<endl; 6 cout<<temp1->a<<endl; 7 delete temp1;//delete it 8 cout<<(int *)temp1<<endl; 9 cout<<temp1->next<<endl; 10 cout<<temp1->a<<endl;
運行結果卻是這樣的:
可以發現,當temp1指向的內存空間被釋放掉后,temp1本身的值並沒有改變,而temp1的next指針的值卻發生了變化。
也就是說,next不再指向專門為其開辟的地址空間。
盡管temp1的地址值沒有變,但是其指向的內存空間的值,被改變了。
那是不是因為next指針不是原來的那塊空間呢?
這里我專門測試了一下,可以講上面的代碼進行一點點的修改,把第五行和第九行的本值輸出改為地址輸出。
你會發現,其值並沒有改變,而且地址相對於temp1的偏移量就是4個字節,一個int值的大小(就是a的空間)。
所以delete刪除一個結構體的時候,並不會修改指針本身的值,但會改寫其指向地址空間的值。
所以,單個指針清空隊列,是不可行的。
這里應該本篇已經到尾聲了,但是有一個很有意思的事情就是,每次程序的輸出后,next的低16位的值都是一樣的。
比如這個:
和上面的輸出結果對比,你會發現第五行的值是一樣的。
這個似乎表明,delete對於釋放后的地址空間,會進行統一的賦值操作。
至於為什么,我不是很清楚,在這就不隨便說自己的猜想了,如果有哪位大神知道,還望指導一二。