指针与储物箱的关系
指針類型是C++、Pascal等語言中比較重要的數(shù)據(jù)類型。在使用上很靈活。在C++中可以使用如下的語句一個(gè)int指針類型: int?*p; 如果要為指針變量賦值,可以使用如下的語句: ????int?x?=?4;
????int?*p;
????p?=?&x;
對(duì)于初學(xué)者來說,可能理解指針比較困難。實(shí)際上,在定義指針變量時(shí),就相當(dāng)于為該指針變量分配一個(gè)32位的內(nèi)存空間(4個(gè)字節(jié)長(zhǎng))來保存內(nèi)存地址(僅限于32位操作系統(tǒng))。為而指針變量賦的值實(shí)際上就是一個(gè)變量(可能是簡(jiǎn)單類型變量,也可能是復(fù)雜類型變量)的首地址。對(duì)于32位操作系統(tǒng)來說,不管是什么類型的變量,地址都是4位的(占一個(gè)int類型的空間)。? 對(duì)于兩個(gè)指向同一個(gè)地址的指針變量,改變一個(gè)指針變量所指向的數(shù)據(jù),都么另一個(gè)指針變量所指向的數(shù)據(jù)也將改變,如下面的代碼所示: ????int?x?=?4;
????int?*p1,?*p2;
????p1?=?&x;??p2?=?&x;
????*p1?=?12;
????printf("%d",?*p2); 上面的代碼將輸出12。
對(duì)于指針的概念及用途,我們也可以做一個(gè)形象的比喻。假設(shè)有兩個(gè)儲(chǔ)物箱A和B。有兩個(gè)人P1和P2。 在A中放置了很多東西,而B是空的。P1擁有A和B的鑰匙,而P2只擁有B的鑰匙。并且P1不能直接給P2鑰匙。 那么P2該如何取得A中的物品呢?(注意,不能直接把A撬開哦,要用鑰匙打開)。
方法嗎有如下兩個(gè): 1.? P1將A和B打開,將A中的物品放在B中。
2.? P1只將B打開,將A的鑰匙放在B中。 第一種方法是直接將A中的物品放在了B中,這么做的好處是無論A發(fā)生的什么事,都不會(huì)影響B(tài)中的物品。但缺點(diǎn)是太麻煩,而且如果A中物品很多的話,是很浪費(fèi)時(shí)間的。而且B的存儲(chǔ)空間要和A的一樣多才能存放A中所有的物品。
第二種方法是P1通過B將A的鑰匙將給了P2,這種方法的好處是方便,而且B也不需要和A一樣大,實(shí)際上,只要能放下一把鑰匙即可。但缺點(diǎn)是A可能不只一把鑰匙,如果其他人使用了A的鑰匙打開A,并動(dòng)了A中的物品,那么會(huì)直接影響到P2所取得的物品。
我們可以將A和B看作是內(nèi)存中的兩個(gè)存儲(chǔ)區(qū)域。對(duì)于第一種方法來說,實(shí)際上相當(dāng)于如下的代碼: ????typedef?struct
????{
?????????int?x
?????????int?y;
?????????float??abc;
????}?MyStruct;
????//??相當(dāng)于A中的物品
????MyStruct?A;
????//??B參數(shù)相當(dāng)于B儲(chǔ)物箱
????void??MyMethod(MyStruct?B)????
????{
??????????
????}
????//??將A中的物品放入B中
???MyMethod(A);
???? 從上面的代碼可以看出,將A傳入MyMethod方法中需要將A中所有的內(nèi)容復(fù)制到MyMethod的方法棧中,這是很耗費(fèi)內(nèi)存資源的。但在MyMethod方法中修改B中的內(nèi)容,并不會(huì)影響到A。但如果使用下面的代碼,就會(huì)是另外一個(gè)樣子。
????//??B參數(shù)只用于保存鑰匙,也就是4個(gè)字節(jié)的指針
????void??MyMethod(MyStruct?*B)????
????{
??????????
????}
????//??將A的鑰匙(指針)放到B中
???MyMethod(&A); 上面的方法很節(jié)省內(nèi)存空間,但在MyMethod方法中修改B指向的結(jié)構(gòu)體中變量的值,也同樣會(huì)影響到A中相應(yīng)變量的值。 讀者在使用指針時(shí),可以將指針相象成儲(chǔ)物箱的鑰匙。當(dāng)定義一個(gè)指針變量時(shí),就相當(dāng)于建立一個(gè)只用于儲(chǔ)放鑰匙的儲(chǔ)物箱。而我們?yōu)檫@個(gè)變量賦值時(shí),只能放鑰匙(指針)或相當(dāng)于鑰匙大小的其他物品。一個(gè)指針變量可以當(dāng)成一個(gè)int變量來使用,如下面的代碼也是正確的:
????int?x?=?1234;
????int?*p;
????p?=?(int*)x;?
??? 上面的代碼將x中的值強(qiáng)行轉(zhuǎn)換成了整型指針,實(shí)際上,這個(gè)指針的值就是1234。也就是說,x變量的值變是一個(gè)內(nèi)存地址了。
??? 那么指針的指針呢,也就是 int **p;,那么我們?cè)偌右粋€(gè)儲(chǔ)物箱C吧。B保存了A的鑰匙,而C保存了B的鑰匙。只要取得了C的鑰匙,就可以按圖索驥地打開A。
也就是說 ,對(duì)于int **p,p中保存了是一個(gè)地址,但這個(gè)地址指向的內(nèi)存空間保存了也是一個(gè)地址,而這個(gè)地址所指向的內(nèi)存空間保存的才是真正的數(shù)據(jù)(int類型)。如果是int ***p,那就再加一個(gè)儲(chǔ)物箱吧。哈哈。 也許有的讀者可能會(huì)注意到本文前面所說的第一種方法是將A中的物品放到B中,那么A中不就沒了,這不就相當(dāng)于把A變量清空了,哈哈,沒錯(cuò)。不過這個(gè)比喻只是為了使讀者更容易理解指針的含義和優(yōu)缺點(diǎn)。如果不想把A清空,就把A中的物品想象成可復(fù)制的就可以了,如光盤,把A中的光盤復(fù)制一份放到B中,那就更麻煩了。哈哈!
?本文轉(zhuǎn)自 androidguy 51CTO博客,原文鏈接:http://blog.51cto.com/androidguy/216686,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
????int?*p;
????p?=?&x;
對(duì)于初學(xué)者來說,可能理解指針比較困難。實(shí)際上,在定義指針變量時(shí),就相當(dāng)于為該指針變量分配一個(gè)32位的內(nèi)存空間(4個(gè)字節(jié)長(zhǎng))來保存內(nèi)存地址(僅限于32位操作系統(tǒng))。為而指針變量賦的值實(shí)際上就是一個(gè)變量(可能是簡(jiǎn)單類型變量,也可能是復(fù)雜類型變量)的首地址。對(duì)于32位操作系統(tǒng)來說,不管是什么類型的變量,地址都是4位的(占一個(gè)int類型的空間)。? 對(duì)于兩個(gè)指向同一個(gè)地址的指針變量,改變一個(gè)指針變量所指向的數(shù)據(jù),都么另一個(gè)指針變量所指向的數(shù)據(jù)也將改變,如下面的代碼所示: ????int?x?=?4;
????int?*p1,?*p2;
????p1?=?&x;??p2?=?&x;
????*p1?=?12;
????printf("%d",?*p2); 上面的代碼將輸出12。
對(duì)于指針的概念及用途,我們也可以做一個(gè)形象的比喻。假設(shè)有兩個(gè)儲(chǔ)物箱A和B。有兩個(gè)人P1和P2。 在A中放置了很多東西,而B是空的。P1擁有A和B的鑰匙,而P2只擁有B的鑰匙。并且P1不能直接給P2鑰匙。 那么P2該如何取得A中的物品呢?(注意,不能直接把A撬開哦,要用鑰匙打開)。
方法嗎有如下兩個(gè): 1.? P1將A和B打開,將A中的物品放在B中。
2.? P1只將B打開,將A的鑰匙放在B中。 第一種方法是直接將A中的物品放在了B中,這么做的好處是無論A發(fā)生的什么事,都不會(huì)影響B(tài)中的物品。但缺點(diǎn)是太麻煩,而且如果A中物品很多的話,是很浪費(fèi)時(shí)間的。而且B的存儲(chǔ)空間要和A的一樣多才能存放A中所有的物品。
第二種方法是P1通過B將A的鑰匙將給了P2,這種方法的好處是方便,而且B也不需要和A一樣大,實(shí)際上,只要能放下一把鑰匙即可。但缺點(diǎn)是A可能不只一把鑰匙,如果其他人使用了A的鑰匙打開A,并動(dòng)了A中的物品,那么會(huì)直接影響到P2所取得的物品。
我們可以將A和B看作是內(nèi)存中的兩個(gè)存儲(chǔ)區(qū)域。對(duì)于第一種方法來說,實(shí)際上相當(dāng)于如下的代碼: ????typedef?struct
????{
?????????int?x
?????????int?y;
?????????float??abc;
????}?MyStruct;
????//??相當(dāng)于A中的物品
????MyStruct?A;
????//??B參數(shù)相當(dāng)于B儲(chǔ)物箱
????void??MyMethod(MyStruct?B)????
????{
??????????
????}
????//??將A中的物品放入B中
???MyMethod(A);
???? 從上面的代碼可以看出,將A傳入MyMethod方法中需要將A中所有的內(nèi)容復(fù)制到MyMethod的方法棧中,這是很耗費(fèi)內(nèi)存資源的。但在MyMethod方法中修改B中的內(nèi)容,并不會(huì)影響到A。但如果使用下面的代碼,就會(huì)是另外一個(gè)樣子。
????//??B參數(shù)只用于保存鑰匙,也就是4個(gè)字節(jié)的指針
????void??MyMethod(MyStruct?*B)????
????{
??????????
????}
????//??將A的鑰匙(指針)放到B中
???MyMethod(&A); 上面的方法很節(jié)省內(nèi)存空間,但在MyMethod方法中修改B指向的結(jié)構(gòu)體中變量的值,也同樣會(huì)影響到A中相應(yīng)變量的值。 讀者在使用指針時(shí),可以將指針相象成儲(chǔ)物箱的鑰匙。當(dāng)定義一個(gè)指針變量時(shí),就相當(dāng)于建立一個(gè)只用于儲(chǔ)放鑰匙的儲(chǔ)物箱。而我們?yōu)檫@個(gè)變量賦值時(shí),只能放鑰匙(指針)或相當(dāng)于鑰匙大小的其他物品。一個(gè)指針變量可以當(dāng)成一個(gè)int變量來使用,如下面的代碼也是正確的:
????int?x?=?1234;
????int?*p;
????p?=?(int*)x;?
??? 上面的代碼將x中的值強(qiáng)行轉(zhuǎn)換成了整型指針,實(shí)際上,這個(gè)指針的值就是1234。也就是說,x變量的值變是一個(gè)內(nèi)存地址了。
??? 那么指針的指針呢,也就是 int **p;,那么我們?cè)偌右粋€(gè)儲(chǔ)物箱C吧。B保存了A的鑰匙,而C保存了B的鑰匙。只要取得了C的鑰匙,就可以按圖索驥地打開A。
也就是說 ,對(duì)于int **p,p中保存了是一個(gè)地址,但這個(gè)地址指向的內(nèi)存空間保存了也是一個(gè)地址,而這個(gè)地址所指向的內(nèi)存空間保存的才是真正的數(shù)據(jù)(int類型)。如果是int ***p,那就再加一個(gè)儲(chǔ)物箱吧。哈哈。 也許有的讀者可能會(huì)注意到本文前面所說的第一種方法是將A中的物品放到B中,那么A中不就沒了,這不就相當(dāng)于把A變量清空了,哈哈,沒錯(cuò)。不過這個(gè)比喻只是為了使讀者更容易理解指針的含義和優(yōu)缺點(diǎn)。如果不想把A清空,就把A中的物品想象成可復(fù)制的就可以了,如光盤,把A中的光盤復(fù)制一份放到B中,那就更麻煩了。哈哈!
?本文轉(zhuǎn)自 androidguy 51CTO博客,原文鏈接:http://blog.51cto.com/androidguy/216686,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
- 上一篇: mac 或linux上 pip 不支持s
- 下一篇: 用API函数播放wav文件声音不连续的解