<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 牛人業(yè)話 > C語(yǔ)言的那些小秘密之指針(二)

          C語(yǔ)言的那些小秘密之指針(二)

          作者: 時(shí)間:2015-03-23 來(lái)源:網(wǎng)絡(luò) 收藏

            懂得的人都知道,之所以強(qiáng)大,以及其自由性,絕大部分體現(xiàn)在其靈活的運(yùn)用上。因此,說(shuō)是c語(yǔ)言的靈魂,一點(diǎn)都不為過(guò)。所以從我的標(biāo)題加了個(gè)(一)也可以看出的重要性,我盡可能的向大家交代清楚我對(duì)于指針的理解。所以在講解的過(guò)程中我盡可能的用代碼加文字的描述方式,通過(guò)代碼的分析來(lái)加深我們對(duì)于指針的理解,我給出的都是完整的代碼,所以讀者可以在看的過(guò)程中直接copy下去即可運(yùn)行,希望下面的講解能夠?qū)δ阌兴鶐椭?/p>本文引用地址:http://www.ex-cimer.com/article/271429.htm

            在此也特地強(qiáng)調(diào)下,如果以后出現(xiàn)類似的情況時(shí),我博客的第一段均作為摘要。如果已經(jīng)在前面的博客中看過(guò)摘要的,那么重復(fù)的摘要部分可跳過(guò)不讀,直接進(jìn)入正文。

            接著上一篇的指針部分,我們接下來(lái)看看數(shù)組的指針和指向數(shù)組的指針變量。數(shù)組的指針就是數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。對(duì)于一個(gè)數(shù)組元素的引用我們通??梢允褂脙煞N方法:

            1、下標(biāo)法,如a[8]。

            2、指針?lè)ā?/p>

            其中使用指針?lè)ǖ膬?yōu)點(diǎn)是使得目標(biāo)程序占內(nèi)存少、運(yùn)行速度快,從而使得其質(zhì)量更高。為什么說(shuō)指針具有這樣的優(yōu)點(diǎn)呢,我想還是有必要在此給出點(diǎn)我解釋,因?yàn)橹羔樤?2位機(jī)器下占用4個(gè)字節(jié),如果函數(shù)傳輸一個(gè)占用內(nèi)存很大的對(duì)象例如:int a[2000],顯然用指針引用傳送簡(jiǎn)單,節(jié)省了內(nèi)存,也節(jié)省了用于復(fù)制對(duì)象的時(shí)間;如果我們用下標(biāo)法來(lái)引用數(shù)組,還得去取數(shù)組的起始地址,通過(guò)base + offset再轉(zhuǎn)換為直接尋址,比指針多了操作。

            從以上可以看出,指針能力很強(qiáng),能完成許多事情,C的精髓就在于指針,使得C能接近ASM的效率。所以我們?cè)趯?xiě)編寫(xiě)程序的時(shí)候有必要充分利用指針的優(yōu)點(diǎn),編寫(xiě)出高效的代碼。

            下面來(lái)看看一個(gè)代碼:

            #include

            #include

            int main()

            {

            int a[8];

            int *p;

            //***************************用下標(biāo)法打印a數(shù)組**************************//

            printf("n***************************用下標(biāo)法打印a數(shù)組**************************n");

            for(int i=0;i<8;i++)

            {

            a[i]=i;

            printf("a[%d]=%dt",i,a[i]);

            }

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            //***************************使用指針變量打印**************************//

            printf("n***************************使用指針變量打印**************************n");

            p=a;

            for(int j=0;j<8;j++)

            {

            printf("p%d=%dt",j,*p++);

            }

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            printf("n");

            //************************用數(shù)組名指針運(yùn)算打印*************************//

            printf("n************************用數(shù)組名指針運(yùn)算打印*************************n");

            for(int k=0;k<8;k++)

            {

            printf("a[%d]=%dt",k,*(a+k));

            }

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            //****************************打印二維數(shù)組b的值地址********************//

            printf("n***************************打印二維數(shù)組b的值及地址*******************n");

            int b[4][4];

            for(int n=0;n<4;n++)

            {

            for(int m=0;m<4;m++)

            {

            b[n][m]=n*m;

            printf("%dt",b[n][m]);

            printf("%dt",&b[n][m]);

            }

            printf("n");

            }

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            int *pp=&b[0][0];

            int **ppp=&pp;

            //*********************二維數(shù)組b的地址、以及pp和*ppp的值****************//

            printf("n*********************二維數(shù)組b的地址、以及pp和*ppp的值****************n");

            printf("n&b[0][0]=%dtpp=%dt*ppp=%dn",&b[0][0],pp,*ppp);

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            //*****************二維數(shù)組b[0][0]、以及*pp和**ppp的值******************//

            printf("n*****************二維數(shù)組b[0][0]、以及*pp和**ppp的值******************n");

            printf("nb[0][0]=%dt*pp=%dt**ppp=%dn",b[0][0],*pp,**ppp);

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            //***************************使用指針變量打印**************************//

            printf("n***************************使用指針變量打印**************************n");

            for(pp=&b[0][0];pp<(&b[0][0]+16);pp++)

            printf("%dt",*pp);

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            printf("n&pp=%dt&ppp=%dn",&pp,&ppp);

            printf("nppp=%dt*ppp=%dn",ppp,*ppp);

            printf("%dt",*(*ppp-1));

            return 0;

            }

            在寫(xiě)上面的代碼時(shí),我加上了很多的注釋,和打印說(shuō)明語(yǔ)句,使得代碼看起來(lái)不怎么美觀,但是它絲毫不會(huì)影響我們對(duì)于代碼的閱讀,下面先讓我們來(lái)看看運(yùn)行結(jié)果后再來(lái)對(duì)齊進(jìn)行分析。

            

           

            上面的圖片可能有點(diǎn)偏大。因?yàn)閳D片看起來(lái)效果更好些,所以我還是把圖片傳上來(lái)的同時(shí)也把打印結(jié)果復(fù)制了一份如下,如果圖片因?yàn)榫W(wǎng)絡(luò)原因打不開(kāi)就看下面的運(yùn)行結(jié)果:

            ***************************用下標(biāo)法打印a數(shù)組**************************

            a[0]=0 a[1]=1 a[2]=2 a[3]=3 a[4]=4 a[5]=5 a[6]=6 a[7]=7

            ****************************end end end******************************

            ***************************使用指針變量打印**************************

            p0=0 p1=1 p2=2 p3=3 p4=4 p5=5 p6=6 p7=7

            ****************************end end end******************************

            ************************用數(shù)組名指針運(yùn)算打印*************************

            a[0]=0 a[1]=1 a[2]=2 a[3]=3 a[4]=4 a[5]=5 a[6]=6 a[7]=7

            ****************************end end end******************************

            ***************************打印二維數(shù)組b的值及地址*******************

            0 1244944 0 1244948 0 1244952 0 1244956

            0 1244960 1 1244964 2 1244968 3 1244972

            0 1244976 2 1244980 4 1244984 6 1244988

            0 1244992 3 1244996 6 1245000 9 1245004

            ****************************end end end******************************

            *********************二維數(shù)組b的地址、以及pp和*ppp的值****************

            &b[0][0]=1244944 pp=1244944 *ppp=1244944

            ****************************end end end******************************

            *****************二維數(shù)組b[0][0]、以及*pp和**ppp的值******************

            b[0][0]=0 *pp=0 **ppp=0

            ****************************end end end******************************

            ***************************使用指針變量打印**************************

            0 0 0 0 0 1 2 3 0 2

            4 6 0 3 6 9

            ****************************end end end******************************

            &pp=1244932 &ppp=1244928

            ppp=1244932 *ppp=1245008

            9 Press any key to continue

            首先來(lái)看看我們使用的三種打印一維數(shù)組a的方法,都成功的對(duì)a數(shù)組中的每個(gè)元素進(jìn)行了打印,接下類是一個(gè)打印二維數(shù)組b的過(guò)程,在打印數(shù)組b中每個(gè)元素的同時(shí)我們也打印出了它相應(yīng)的地址,細(xì)心的讀者可能發(fā)信地址間的規(guī)律,因?yàn)槲覀兟暶鞯氖莍nt型,所以每個(gè)元素占用4個(gè)字節(jié),相鄰元素間的地址之差為4。

            接下來(lái)我們使用了一個(gè)指針pp和一個(gè)指向指針的指針ppp,在使用指針的指針ppp的過(guò)程中要尤其注意它的使用。通過(guò)打印語(yǔ)句我們打印出了&b[0][0],pp,*ppp,其都具有相同的結(jié)果,都為二維數(shù)組b[0][0]的地址,所以接下來(lái)打印的b[0][0],*pp,**ppp均為b[0][0]的值,接下來(lái)我們采用指針的方法來(lái)成功的打印了二維數(shù)組b。

            在接下來(lái)我們打印出了指針pp、雙指針ppp的地址,同時(shí)也打印了ppp和*ppp的值,注意了*ppp的值和最后一次打印的數(shù)組元素的地址的關(guān)系,為什么會(huì)出現(xiàn)這樣的結(jié)果呢,因?yàn)槲覀兦懊媸褂昧艘痪鋓nt **ppp=&pp;,使得*ppp和pp指向的是同一個(gè)存儲(chǔ)空間,其地址為&pp=1244932 ,所以在改變pp的值得時(shí)候,*ppp的值也在跟隨其改變。所以細(xì)心的讀者可能發(fā)現(xiàn)了在最后一句打印語(yǔ)句printf("%dt",*(*ppp-1));中,我們使用了*(*ppp-1)才能成功的打印出二維數(shù)組b的最后一個(gè)最后一個(gè)元素。

            如何采用二維指針類打印數(shù)組呢,請(qǐng)看下面的代碼:

            #include

            int main()

            {

            //****************************打印二維數(shù)組b的值地址********************//

            printf("n***************************打印二維數(shù)組b的值及地址*******************n");

            int b[4][4];

            for(int n=0;n<4;n++)

            {

            for(int m=0;m<4;m++)

            {

            b[n][m]=n*m;

            printf("%dt",b[n][m]);

            printf("%dt",&b[n][m]);

            }

            printf("n");

            }

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            int *pp=&b[0][0];

            int **ppp=&pp;

            //****************************使用二維指針的打印數(shù)組b*******************//

            printf("n***************************使用二維指針的打印數(shù)組b*******************n");

            for(*ppp;*ppp<(&b[0][0]+16);(*ppp)++)

            printf("%dt",**ppp);

            printf("n****************************end end end******************************n");

            //****************************end end end******************************//

            return 0;

            }

            運(yùn)行結(jié)果如下:

            

           

            注意代碼中我們的紅色標(biāo)記部分,很多人在采用二維指針**ppp進(jìn)行打印的時(shí)候最容易出錯(cuò)的地方,很多人使用的是如下方式:

            for(*ppp;*ppp<(&b[0][0]+16);*ppp++)

            看似沒(méi)有問(wèn)題,似乎能得到正確的結(jié)果,但是我們仔細(xì)分析就會(huì)發(fā)現(xiàn)其中的問(wèn)題所在,因?yàn)?+的優(yōu)先級(jí)高于*,所以首先進(jìn)行的是ppp++運(yùn)算,然后才是*ppp,這樣的話就出現(xiàn)我們前面所講的野指針的問(wèn)題了。所以在調(diào)用printf("%dt",**ppp);就會(huì)出現(xiàn)內(nèi)存錯(cuò)誤。所以在此我們需要加上一個(gè)括號(hào)(*ppp)++,這樣*ppp中的才是b[0][0]的地址,接下來(lái)通過(guò)使用++操作和printf("%dt",**ppp);才能成功的打印出二維數(shù)組b的元素。

          c語(yǔ)言相關(guān)文章:c語(yǔ)言教程




          關(guān)鍵詞: C語(yǔ)言 指針

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();