這篇文章主要介紹“C++中指針實(shí)例分析”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“C++中指針實(shí)例分析”文章能幫助大家解決問題。
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比秭歸網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式秭歸網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋秭歸地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。
CPU是計(jì)算機(jī)的核心部件,要想讓一個(gè)CPU工作,就必須向它提供指令和數(shù)據(jù),指令和數(shù)據(jù)在存儲(chǔ)器中存放,也就是我們平時(shí)說的內(nèi)存。
內(nèi)存分為:物理內(nèi)存和虛擬內(nèi)存,物理內(nèi)存對(duì)應(yīng)著計(jì)算機(jī)中的內(nèi)存條,虛擬內(nèi)存是操作系統(tǒng)內(nèi)存管理系統(tǒng)假想出來的,由于這些不是我們本文的重點(diǎn),我們就不做區(qū)分。
在不考慮cpu緩存的情況下,計(jì)算機(jī)運(yùn)行程序本質(zhì)上是對(duì)內(nèi)存中的數(shù)據(jù)的操作,存儲(chǔ)器被劃分為多個(gè)存儲(chǔ)單元,存儲(chǔ)單元從零開始順序編號(hào),CPU要從內(nèi)存中讀取數(shù)據(jù),首先要指定存儲(chǔ)單元的地址。
CPU從內(nèi)存中讀取數(shù)據(jù)的過程如圖所示:
計(jì)算機(jī)為了方便管理內(nèi)存,將內(nèi)存的每個(gè)單元用一個(gè)數(shù)字編號(hào)
指針的本意就是內(nèi)存地址,我們可以通俗的理解成內(nèi)存編號(hào),既然計(jì)算機(jī)通過編號(hào)來操作內(nèi)存單元,這就造成了指針的高效率
指針變量:
通俗理解為存儲(chǔ)指針的變量,也就是存儲(chǔ)內(nèi)存地址(內(nèi)存編號(hào))的變量
指針變量和int,float,char等類型一樣同屬變量類型,指針變量類型占四個(gè)字節(jié)(32位機(jī)器下),存儲(chǔ)的是32位的內(nèi)存地址
星號(hào):
在CC++中(*)被定義為取內(nèi)容符號(hào)
雖然所有指針變量占的內(nèi)存大小和存儲(chǔ)的內(nèi)存地址大小都是一樣的,但是由于存儲(chǔ)的只是數(shù)據(jù)的內(nèi)存首地址,所以指針變量存儲(chǔ)的內(nèi)存地址所指向的數(shù)據(jù)類型決定著如何解析這個(gè)首地址
比如int型指針變量,我們需要從該指針變量存儲(chǔ)的首地址開始向后一直搜索4個(gè)字節(jié)的內(nèi)存空間
所以當(dāng)我們使用*p,必須知道p是一個(gè)什么類型的指針
指針變量首先是一個(gè)變量,由于指針變量存儲(chǔ)了某個(gè)變量的內(nèi)存首地址,我們通常認(rèn)為"指針變量指向了該變量",同時(shí)指針變量時(shí)一個(gè)變量,它的值是可以變動(dòng)的。
相反,指針常量可通俗地理解為存儲(chǔ)固定的內(nèi)存單元地址編號(hào)的量,它一旦存儲(chǔ)了某個(gè)內(nèi)存地址以后,不可再改存儲(chǔ)其他的內(nèi)存地址了
舉個(gè)例子:
void f(const int *x,int *y) { *x=2;//錯(cuò)誤,由于x前面有個(gè)const修飾,所以不可以修改x所指向的內(nèi)存單元的內(nèi)容 //正確寫法 *y=3; }
先看一個(gè)例子:
int a[5]={1,2,3,4,5}; int *ptr=(int*)(&a+1); cout<<*(a+1)<輸出結(jié)果為2和5,首先我們看一下&a+1的含義:
我們知道CC++中規(guī)定數(shù)組名表示這個(gè)數(shù)組的首地址,而這里出現(xiàn)了&a這樣的符號(hào),本來a就是指針常量,再次取地址難道不是非法操作?
這時(shí)我們可以將這個(gè)&a看成是指向數(shù)組的指針,也稱為行指針,&a的類型是int (*p)[5],一個(gè)步長(zhǎng)即5個(gè)元素的長(zhǎng)度,&a + 1代表往后移動(dòng)一個(gè)步長(zhǎng)
分析:
a表示的是第一個(gè)元素的首地址,那么a+1指向的就是下一個(gè)元素的內(nèi)存首地址,所以*(a+1)=2
而&a則表示整個(gè)數(shù)據(jù)的首地址,那么&a+1移動(dòng)的內(nèi)存數(shù)目就是整個(gè)數(shù)組所占字節(jié)數(shù),假如原先數(shù)組中第一個(gè)元素的首地址是0,那么&a+1表示的就是20,而這個(gè)地址已經(jīng)不屬于數(shù)組了,接著通過(int*)(&a+1)將數(shù)組指針轉(zhuǎn)換成整型指針,這樣原先&a+1表示的數(shù)據(jù)范圍20-39就縮小為20-23,正好是一個(gè)int型的大小,而ptr-1就是16了,表示的數(shù)據(jù)內(nèi)存范圍是16-19,這樣*(ptr-1)正好是最后一個(gè)元素5了
上面的例子,只是通過簡(jiǎn)單的數(shù)據(jù)類型來說明內(nèi)存分布,但是實(shí)際上一些復(fù)雜的數(shù)據(jù)類型,尤其是一些自定義的類或者結(jié)構(gòu)體類型,內(nèi)存分布還要充分考慮到字節(jié)對(duì)齊。
函數(shù)指針
函數(shù)指針是指向函數(shù)的指針變量,CC++程序在編譯時(shí),每個(gè)函數(shù)都有一個(gè)入口地址,該入口地址就是函數(shù)指針?biāo)赶虻牡刂?,有了指向函?shù)的指針變量后,可用該指針變量調(diào)用函數(shù),同時(shí)也可以做函數(shù)的參數(shù)
我們先看函數(shù)指針調(diào)用函數(shù),如下:
int f(int x, int y) { return x + y; } //申明一個(gè)函數(shù)指針 typedef int (*pf)(int, int); int main() { int a = 1; int b = 2; //將函數(shù)f地址賦給函數(shù)指針pf pf = f; //利用函數(shù)指針調(diào)用函數(shù) int c = (*pf)(a, b); cout << c << endl; }需要注意的是,定義的函數(shù)指針類型時(shí)的函數(shù)簽名(包括函數(shù)返回值和函數(shù)參數(shù)列表的類型,個(gè)數(shù),順序)要將賦值給該類型變量的函數(shù)簽名保持一致,不然可能會(huì)發(fā)生很多無法預(yù)料的情況,還有CC++規(guī)定函數(shù)名就表示函數(shù)入口地址,所以,函數(shù)名賦值時(shí)函數(shù)名前面加不加取地址符&都一樣,但是在C++中取類的方法函數(shù)的地址時(shí),這個(gè)&符號(hào)不能省略。
函數(shù)指針還有另外一個(gè)用處,就是作為一個(gè)函數(shù)的參數(shù),在Windows編程中作為回調(diào)函數(shù)很常見:
typedef int (*PF)(int, int); int f1(int x, int y) { return x + y; } int f2(PF pf, int t) { return (*pf)(3, t); } int main() { //將函數(shù)f1作為參數(shù)傳遞給函數(shù)f2 int c = f2(f1, 4); cout << c << endl; return 0; }C++中的引用
所謂引用,使用另外一個(gè)變量名來代表某一塊內(nèi)存,這就相當(dāng)于同一個(gè)人有不同的名字,但是不管哪個(gè)名字,指的都是同一個(gè)人。
int a=1; //通過&符號(hào),將b定義為a的引用 int &b=a; //b和a完全一樣,等價(jià)于int c=a int c=b;注意,C++規(guī)定,定義一個(gè)引用的時(shí)候,必須馬上初始化
傳值還是傳引用
如果變量類型是基元數(shù)據(jù)類型,比如int,float,bool,char等小數(shù)據(jù)類型被稱為基元數(shù)據(jù)類型,那么賦值時(shí)傳的是值,這時(shí)候b的值是a的拷貝,那么更改b不會(huì)影響到a,但是,如果變量數(shù)據(jù)類型是復(fù)雜數(shù)據(jù)類型,比如數(shù)組,類對(duì)象,那么賦值時(shí)傳的就是引用,這個(gè)時(shí)候,a和b指向的都是同一個(gè)內(nèi)存區(qū)域,那么無論更改a或者b都會(huì)相互影響。
最后,在利用C++中拷貝構(gòu)造函數(shù)復(fù)制對(duì)象時(shí)需要注意,基元數(shù)據(jù)類型可以直接復(fù)制,但是對(duì)于引用類型數(shù)據(jù),我們需要實(shí)現(xiàn)引用類型的真正復(fù)制
C++中的new關(guān)鍵詞
在c++中通過new關(guān)鍵詞定義一個(gè)對(duì)象,不能直接得到對(duì)象的實(shí)例,我們需要用一個(gè)指針去接收這個(gè)new出來的對(duì)象,我們引用這個(gè)對(duì)象必須使用指針引用運(yùn)算符->
#includeusing namespace std; class Person { public: Person() { } Person(int a, int b) { this->m_a = a; this->m_b = b; } int m_a; int m_b; }; int main() { //在C++中可以用以下形式來實(shí)例化一個(gè)對(duì)象,per1和per2為實(shí)例化的person類對(duì)象 Person per1; int i = 1; int j = 2; Person per2(i, j); } 在C++中,this關(guān)鍵詞是一個(gè)指針,而不像在java中是一個(gè)類實(shí)例,在C++中*this才等價(jià)于java
class Person { public: Person(int number) { //C++中需要使用指針引用符號(hào) this->m_number = number; } //返回對(duì)象本身,,需要使用引用,因?yàn)榉祷刂禃r(shí)會(huì)創(chuàng)建一個(gè)新的對(duì)象,使用引用的方式不會(huì)創(chuàng)建新的對(duì)象 Person& getSelf() { return *this; } int m_number; };關(guān)于“C++中指針實(shí)例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
當(dāng)前名稱:C++中指針實(shí)例分析
鏈接URL:http://weahome.cn/article/jghepp.html