天天看點

指針的思考

指針從幾年前就開始接觸到了,當時我的腦子裡對指針沒有概念,隻知道它就像他的名字一樣 它可以指向一個資料進行修改或者調用。結果确實如此,命名的人很有智慧。

聽那些老一代的程式員所寫的部落格和論壇的評論,說這個東西是C語言的靈魂,如果運用不恰當會對程式造成極大的破壞,甚至造成記憶體的洩露。

從那之後對于指針我就會産生一種莫名的恐懼感,甚至看見它關于它的兩個操作符号我也會心中産生一種反感。就是那個*與&操作符。

是以我盡量的用數組或者全局變量,忽略了指針。幾乎每次的程式我完全不用指針,也發現這東西完全可以不用。程式裡不用指針這個程式看起來簡約、工整。

但是今年偶然間用到它的時候,發現我以前的恐懼和擔心,都是錯誤的。

我以前自己寫一寫小的程式也就是按照自己的思路走的,包括整個程式的架構、函數封裝等等。

 今年2014年,有一個同學想跟我一起設計一個基于VisualC++ 6.0平台下的一個Windows遊戲,也就是當時比較有名的手機遊戲2048,他是負責遊戲的圖像互動的,我就是背景那個給予他一切資料處理的頭檔案或者函數。為了能夠更好的進行分工,他對我的要求就是能夠把他的簡單資料給我,我經過一系列的加工處理再把這些處理好的資料返還給他,後來為了能夠更好地互動,想來想去,也就隻有指針可以實作這個功能了。全局變量根本不可行,全局變量在他的電腦上,我這裡隻能做一些功能性的函數了。筆記:指針并非抽象概念,他是一種類型,就叫做指針類型,正如整形、浮點、布爾一樣,隻不過它隻能儲存其他變量的記憶體位址。它自己也占用記憶體。

指針有了資料記憶體位址以後,就可以修改這個記憶體位址上的資料,它簡直太好用了。它甚至可以放到函數的參數裡,基本就像一個綠色通道,對外面世界的東西進行通路、修改、操作等等,基本什麼事情都能做。

 舉個例子:

int Add(int a,int b)

{

        return (a + b);

}

用起來就是

 int a = 100,b = 100;

int c = Add(a,b);

定義整形a、b,并各指派100,再把他們的之和相加給予c最後就是:

 a為100 b為100 c為200這個例子就是把外面的兩個整形帶到函數裡相加,在傳回一個整形,就是他們的之和。

看看指針能夠怎麼實作他的功能強大之處

int Add(int *a,int *b)

{

            int c = *a + *b;*a = 0,*b = 0;

            return c;

}

用起來就是

 int a = 100,b =100;

int c = Add(&a,&b);

結果發生了什麼?

 就是:a為0 b為0 c為200

指針通過函數把外面世界的變量給改掉了。以前的的想法隻有一種可能,就是把他們a、b設為全局變量進行修改現在不用了,a、b在哪裡都無所謂,隻要他們通過指針,把位址傳入到函數裡,就可以在函數裡面對這些記憶體位址上的東西進行修改。

從那次運用過指針的強大以後,基本以後的任何程式就離不開指針了,靜态變量甚至都可以不用了

因為指針可以指向空的記憶體位址,對空的記憶體位址進行合理的使用、修改、釋放。

最後才發現數組也就是連續的一排空的記憶體位址,完全可以用指針進行動态開辟。

指針開辟記憶體所成為的數組,就是靈活的,他的大小是靈活多變的,他的位址甚至不用連續。

比如定義一個空的指針int *p;

好,這個指針裡面沒有位址,那麼我給他配置設定10個長度為int長度的位址

 p = (int *)malloc(10*sizeof(int));

好了,這回指針開辟了10個連續的大小為int整形的記憶體(或者說記憶體位址)如何用呢??

完了,這個指針一小心成為了數組了^-^

怎麼用呢,用法不是跟數組一樣嗎

p[10] = {1,2,3,4,5,6,7,8,9,0};

這樣就給這個10記憶體位址存入内容了,也許會問,這不是成為數組了嗎,對就是數組。它也是指針!!

 我們剛才發生了什麼?那麼整理一下思路,指針的思路。

 1.指針就是一個變量,它自己也占用記憶體。

 2.它裡面儲存的資料是記憶體位址。

 3.這個指針可以被操作,一進制運算符*與&

 4.*<指針變量>代表擷取、操作指針所指向/儲存記憶體位址上的值

 5.&<任何變量>代表擷取該變量的位址

圖像法表示指針就是例如:

指針變量    内部存儲的記憶體位址 :0xffffffff

                  自己占用的記憶體位址 :0x00000000

0xffffffff 自己所指向的位址

 0x00000000 自己占用記憶體位址(因為指針自己就是個變量)

 定義一個int*p;

那麼這個指針裡面沒有儲存東西int a =100;

&a就是用這個運算符取出a的記憶體位址p = &a;

把整形a的位址存到了指針p裡面

這樣*p就是100了

但是有很多人寫指針的方式有點問題,會給很多初學的人造成了很大的麻煩!

就是這樣定義 int *p;

雖然運作成功,但是沒有可讀性。其實這樣是不對的,應該這樣 int* p (整形指針p)

 *p不是調用記憶體位址上的值嗎?是以int*p???

當然讓人誤解之前的那個函數就可以寫成了

 int Add(int* a,int* b)

{

            int c = *a + *b;

            *a = 0,*b = 0;

return c;

}

參數裡的指針定義就有強的的可讀性為了更加明确變量的可讀性,能讓人認出這個是指針就在前面加一個小p,代表pointer

int Add(int* pa,int* pb)

{

            ........

}這樣寫未嘗不可。

 這樣指針分一下類别就有:int*型    float*型    double*型    char*型    void*型    struct*型    *<變量名>()型.........

                                                                                                                                                ^這個是函數指針型

以後還有更多的指針用法。。。