欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      關(guān)于指針的一些總結(jié)

      時(shí)間:2019-05-13 03:28:05下載本文作者:會(huì)員上傳
      簡(jiǎn)介:寫(xiě)寫(xiě)幫文庫(kù)小編為你整理了多篇相關(guān)的《關(guān)于指針的一些總結(jié)》,但愿對(duì)你工作學(xué)習(xí)有幫助,當(dāng)然你在寫(xiě)寫(xiě)幫文庫(kù)還可以找到更多《關(guān)于指針的一些總結(jié)》。

      第一篇:關(guān)于指針的一些總結(jié)

      如果const在*左邊,const修飾值intconst*pi

      如果const在*右邊,const修飾指針int*constpi;

      其實(shí)這種問(wèn)題你可以這樣看,const后面如果有*p之類的,就是p能改,*p不能改,也就是指針能改,指針的值不能改,intconst*p后面有*p,所以是*p不能改,int*constp是p不能改,*p能改~!其他的類似。

      constint*p;

      intconst*q;

      int*constr=&i;

      1,聲明了一個(gè)指針p,它指向一個(gè)int型的常量,p可以再指向別的變量,但這個(gè)int型的值不能被改變

      2,同上.3,聲明了一個(gè)常指針p,它被一個(gè)int型變量的地址初始化,這個(gè)指針將不再允許指向別的變量,而這個(gè)int變量的值是可以改變的。

      const修飾指針和引用的用法,對(duì)于初學(xué)C++的人直是諱莫如深,不知所云.一旦你了解了其用法,一切便不值一哂了.下面我為讀者一一釋疑:

      大致說(shuō)來(lái)其可分為三種情況:const修飾指針,const修飾引用,const修飾指針的引用.1.const修飾指針

      const修飾指針又可分為三種情況:

      const修飾指針本身

      const修飾指針?biāo)傅淖兞?或?qū)ο?

      const修飾指針本身和指針?biāo)傅淖兞?或?qū)ο?

      (1).const修飾指針本身

      這種情形下,指針本身為常量,不可改變,任何修改指針本身的行為都是非法的.例如:constinta=1;

      constintb=2;

      inti=3;

      intj=4;

      int*constpi=&i;//ok,pi的類型為int*const,&i的類型為int*const

      int*constpi=&a;//error,pi的類型為int*const,&a的類型為constint*const

      pi=&j;//error,指針是常量,不可變

      *pi=a;//ok,*pi并沒(méi)有限定是常量,可變

      由此看出,pi是常量,常量在初始化和賦值時(shí),類型必須嚴(yán)格一致。也就是const修飾指針本身時(shí),=號(hào)兩邊的變量類型必須嚴(yán)格一致,否則不能匹配。

      (2).const修飾指針指向的變量(或?qū)ο?

      此種情形下,通過(guò)間接引用指針不可改變變量的值,假設(shè)指針為p,則*p不可變,下面以例子說(shuō)明:

      constint*pi=&a;

      //orintconst*pi=&a;

      //兩者毫無(wú)二致,不過(guò)BS喜歡前者,這也沒(méi)什么技術(shù)上的優(yōu)劣之分,也就是說(shuō)constint與intconst可以互換.建議大家熟

      //悉這兩種形式,為簡(jiǎn)潔便,以后統(tǒng)統(tǒng)用前者.//ok,const并不修飾指針本身,pi對(duì)賦值類型

      //沒(méi)要求,但pi是int*型指針,所以所賦的必須是個(gè)地址值。

      constint*pi=&i;//ok,pi可賦值常量的地址,又可賦變量的地址

      constint*pi1=&a;

      constint*pi=pi1;//ok

      *pi=j;//error,*pi不可變,不能更改指針的間接引用形式

      pi=&j;//ok,pi可變

      pi=&b;//ok,pi可變

      pi++;//ok

      --pi;//ok

      由此可見(jiàn),pi是變量,可以賦值常量和變量的值,正如一個(gè)整型變量可賦整型數(shù)和整型變量一樣.const修飾的不是指針本身,而是其間接引用,=號(hào)兩邊的類型不必嚴(yán)格匹配,如:constint*pi=&a;中,pi的類型為int*,而&a的類型為constint*const,只要其中含有int*就可以。又如:constint*pi=&j;中,pi的類型為int*,而&j的類型為int*const,它向pi賦值并無(wú)大礙。

      (3)const修飾指針本身和指針?biāo)傅淖兞?或?qū)ο?

      設(shè)有指針p,此種情形下,p和*p都不可變.舉例如下:

      constint*constpi=&a;

      //orintconst*constpi=&a;

      //將constpi看作一體,就與(2)所述相同,只是要求pi必須為const,正如上所說(shuō),=號(hào)兩邊的類型不必嚴(yán)格匹配,但必須含有int*,&a的類型為constint*const,含有int*,所以可以賦值。constint*constpi=&i;//ok,&i類型為int*const,含有int*,可賦值。

      constint*pi1=&j;

      constint*constpi=pi1;//ok,pi1類型為int*

      pi=&b;//error,pi不可變

      pi=&j;//error,pi不可變

      *pi=b;//error,*pi不可變

      *pi=j;//error,*pi不可變

      pi++;//error,pi不可變

      ++i;//ok,=號(hào)右邊的變量(或?qū)ο?與所修飾的變量無(wú)關(guān)

      a--;//error,a為const

      這種情況,跟以上兩種情形有聯(lián)系。對(duì)constint*constpi=&a;我們可以這樣看:constint*(constpi)=&a;(僅僅是表達(dá)需要),將constpi看作一體,就與上述分類(2)符合。只要含有int*便可.2.const修飾引用

      這種情況比較簡(jiǎn)單,沒(méi)有象修飾指針那樣繁復(fù),因?yàn)橐煤鸵脤?duì)象是一體的,所以引用被const修飾只有一種類型。

      const修飾引用,引用本身不可變,但引用的變量(或?qū)ο?可以改變.例如:

      constint&ri=a;//orintconst&ri=a;ok,ri本身是常量,引用不區(qū)分類型

      constint&ri=i;//ok,引用不區(qū)分類型

      ri++;//error,ri為常量,不可變

      i++;//ok,=右邊的變量與引用無(wú)關(guān)

      ri=b;//error,ri為常量

      i=j;//ok,=右邊的變量與引用無(wú)關(guān)

      int&constri=i;//error,不存在這種形式,沒(méi)有意義

      3.const修飾指針的引用

      引用只是個(gè)別名,這里與修飾指針類似,又分為三種情況:

      (1)

      先給個(gè)例子:

      constint*pi=&a;

      constint*&ri=pi;

      //orintconst*&ri=pi;

      引用是引用對(duì)象的別名,正因?yàn)槿绱?,ri是pi的別名,所以ri的類型必須與pi完全一致才行。這里pi的類型為int*,ri的類型也為int*,賦值可行。若constint*&ri=&a;正不正確?分析一下就知曉。ri類型為int*,&a的類型則為constint*const不匹配。

      constint*&ri=&i;//error,類型不匹配,一為int*,一為int*constri=&a;//ok

      ri=&i;//ok

      constint*pi1=&a;

      constint*pi2=&i;

      ri=pi1;//ok

      ri=pi2;//ok

      *ri=i;//error

      *ri=a;//error

      注意這與1-(2)的區(qū)別.(2)

      用例子說(shuō)明:

      int*const&ri=&i;

      去掉ri左邊的&號(hào),則為int*constri,因?yàn)閞i是別名,故ri的類型應(yīng)與賦值的數(shù)類型一致,ri類型為int*const,&i為int*const,可以這么做.int*const&ri=pi;//error,類型不合,一為int*const,一為int*int*const&ri=&a;//error,類型不合,一為int*const,一為constint*const

      (*ri)++;//ok

      i++;//ok

      ri=&i;//error

      這種情況下,ri為常量,不可更改.(3)

      用例子說(shuō)明:

      constint*pi=&j;

      constint*const&ri=pi;//orintconst*const&ri=pi;ok

      constint*const&ri=&i;//ok

      ri是pi的別名,pi的類型應(yīng)與ri一致。拿掉&,得constint*constri,把constri看作一體,很容易得出ri的類型信息,就象前面2-(3)所討論的一樣,可以得到賦給ri的只要含有類型int*即可。pi的類型為int*,&i的類型為int*const,可以這么做.constint*const&ri=&a;//ok

      ri++;//error

      *ri=6;//error

      第二篇:指針概念知識(shí)點(diǎn)總結(jié)--經(jīng)典

      指針概念知識(shí)點(diǎn)

      ● 變量的地址就是變量的指針。變量的值和變量的地址是不同的概念,變量的值是該變量在內(nèi)存單元中的數(shù)據(jù)。用來(lái)存放指針(地址)的變量就稱為指針變量。

      ● 若把某變量的地址賦值給指針變量p,則稱指針變量p指向該變量。

      ● 定義指針變量的一般形式為:類型名*指針變量名;,其中“*”為說(shuō)明符,而不是運(yùn)算符。

      ● 通常指針變量可以通過(guò)以下幾種方法獲得地址:通過(guò)地址運(yùn)算“&”賦值,指針變量的初始化,通過(guò)其他指針變量賦值,用NULL給指針變量賦空值,以及通過(guò)調(diào)用標(biāo)準(zhǔn)函數(shù)賦值。

      ● “*”稱為指針運(yùn)算符(單目運(yùn)算符),也稱取內(nèi)容運(yùn)算符。當(dāng)指針變量p指向一個(gè)變量x時(shí),可以用*p的形式存取該變量的值。此時(shí),*p與變量x相互等價(jià)。

      ● 取地址運(yùn)算符“&”與指針運(yùn)算符“*”作用在一起時(shí),有相互“抵消”的作用。對(duì)于變量x,*&x與x相互等價(jià)。

      ● 若定義了一維數(shù)組a和指針變量p,且p=a;,則以下四種表示相互等價(jià):a[i]、p[i]、*(a+i)、*(p+i)。

      ● 未對(duì)指針變量p賦值即p沒(méi)有指向時(shí),而就對(duì)*p賦值,該值就代替了內(nèi)存中某單元的內(nèi)容,有可能出現(xiàn)不可意料的錯(cuò)誤。

      ● 一個(gè)數(shù)組的元素在內(nèi)存中是連續(xù)存放的,數(shù)組第一個(gè)元素的地址稱數(shù)組的首地址。在C語(yǔ)言中,數(shù)組名是該數(shù)組的首地址,因此,數(shù)組名是指針常量。

      ● 當(dāng)指針變量p指向數(shù)組元素時(shí),p加上一個(gè)正整數(shù)n,則當(dāng)前指向?yàn)橄鄬?duì)p向前移動(dòng)n個(gè)元素的位置;p減去一個(gè)正整數(shù)n,則當(dāng)前指向?yàn)橄鄬?duì)p向后移動(dòng)n個(gè)元素的位置。

      ● 假設(shè)指針變量p、q指向同一數(shù)組,若p指向地址較大元素,q指向地址較小的元素,則p>q的值為1(真),且p

      ● 假設(shè)指針變量p、q指向同一數(shù)組,p-q的值等于p所指對(duì)象與q所指對(duì)象之間的元素個(gè)數(shù),若p>q則取正值,p

      ● 把字符串常量賦值給字符指針變量,相當(dāng)于把該字符串常量的首地址賦值給字符指針變量。

      ● C語(yǔ)言的二維數(shù)組由若干個(gè)一維數(shù)組構(gòu)成。若有定義語(yǔ)句:int a[M][N], i, j;,則以下元素的七種表示相互等價(jià):a[i][j]、*(a[i]+j)、*(*(a+i)+j)、(*(a+i))[j]、*(&a[0][0]+N*i+j)、*(a[0]+N*i+j)、*(*a+N*i+j)。

      ● 若有語(yǔ)句:int a[M][N], i, j,(*pi)[N];,則指針變量pi指向“包含N個(gè)整型元素的一維數(shù)組”。當(dāng)pi=a;時(shí),pi+1將跳過(guò)N個(gè)元素指向下一行,故稱pi為行指針,也稱pi是(指向一維)數(shù)組(的)指針。若pi=a;,則以下五種元素的表示相互等價(jià):a[i][j]、pi[i][j]、*(pi[i]+j)、*(*(pi+i)+j)、(*(pi+i))[j]。

      ● 除了由二維字符數(shù)組可以構(gòu)成字符串?dāng)?shù)組外,還可以定義一個(gè)指針數(shù)組,并在定義時(shí)用字符串賦初值的方法,構(gòu)成一個(gè)字符串?dāng)?shù)組。

      ● 指向指針的指針變量,經(jīng)過(guò)二次間接存取后才能存取到變量的值。

      ● 通常用指針數(shù)組的每個(gè)元素pa[i]指向二維數(shù)組a的每行第0列元素的首地址,然后用指向指針的指針變量pp指向指針數(shù)組,此時(shí),pp+1指向數(shù)組指針pa的下一個(gè)元素,也就是 pp+1指向二維數(shù)組a的下一行。如果a是二維字符數(shù)組,則pp+1指向下一個(gè)字符串。

      ● 當(dāng)指針變量指向某一結(jié)構(gòu)體變量時(shí),可用下述三種方式之一存取結(jié)構(gòu)體成員(三種方式是等價(jià)的):結(jié)構(gòu)體變量名.成員名、指針變量名->成員名、(*指針變量名).成員名。

      ●若p指向數(shù)組a,則:⑴ p++(或p+=1),使p指向下一元素。⑵ *p++等價(jià) *(p++)。作用是先得到p指向的變量的值(即*p),然后再使p+1→p。⑶ *(p++)與*(++p)不同。前者為a[0],后者為a[1]。⑷(*p)++表示p指向的元素值加1,即(a[0])++⑸ 如果p當(dāng)前指向a數(shù)組中第i個(gè)元素,則: *(p--)相當(dāng)于a[i--],先對(duì)p進(jìn)行*運(yùn)算,再使p自減; *(++p)相當(dāng)于a[++i],先使p自加,再作*運(yùn)算。*(--p)相當(dāng)于a[--i],先使p自減,再作*運(yùn)算。

      第三篇:史上最全C語(yǔ)言指針總結(jié)

      C語(yǔ)言中的精華是什么,答曰指針,這也是C語(yǔ)言中唯一的難點(diǎn)。

      C是對(duì)底層操作非常方便的語(yǔ)言,而底層操作中用到最多的就是指針,以后從事嵌入式開(kāi)發(fā)的朋友們,指針將陪伴我們終身。

      本文將從八個(gè)常見(jiàn)的方面來(lái)透視C語(yǔ)言中的指針,當(dāng)然,還有其他沒(méi)有具體提到的方面,像指針表達(dá)式、指針安全等問(wèn)題,以后有機(jī)會(huì)我再慢慢補(bǔ)充。

      還是那句老話,重要的是實(shí)踐,多寫(xiě)代碼,才是學(xué)好C語(yǔ)言的關(guān)鍵。1.指針類型分析

      分析指針,可以從變量名處起,根據(jù)運(yùn)算符優(yōu)先級(jí)結(jié)合,一步一步分析.int p;//這是一個(gè)普通的整型變量

      int *p;//首先從P處開(kāi)始,先與*結(jié)合,所以說(shuō)明P是一個(gè)指針,然后再與int結(jié)合,說(shuō)明指針?biāo)赶虻膬?nèi)容的類型為int 型.所以 P是一個(gè)返回整型數(shù)據(jù)的指針

      int p[3];//首先從P處開(kāi)始,先與[]結(jié)合,說(shuō)明P 是一個(gè)數(shù)組,然后與int結(jié)合,說(shuō)明數(shù)組里的元素是整型的,所以 P是一個(gè)由整型數(shù)據(jù)組成的數(shù)組

      int *p[3];//首先從P處開(kāi)始,先與[]結(jié)合,因?yàn)槠鋬?yōu)先級(jí)比*高,所以P是一個(gè)數(shù)組,然后再與*結(jié)合,說(shuō)明數(shù)組里的元素是指針類型,然后再與 int結(jié)合,說(shuō)明指針?biāo)赶虻膬?nèi)容的類型是整型的,所以是一個(gè)由返回整型數(shù)據(jù)的指針?biāo)M成的數(shù)組

      int(*p)[3];//首先從P處開(kāi)始,先與*結(jié)合,說(shuō)明P是一個(gè)指針然后再與[]結(jié)合(與“()”這步可以忽略,只是為了改變優(yōu)先級(jí)),說(shuō)明指針?biāo)赶虻膬?nèi)容是一個(gè)數(shù)組,然后再與int 結(jié)合,說(shuō)明數(shù)組里的元素是整型的.所以P是一個(gè)指向由整型數(shù)據(jù)組成的數(shù)組的指針

      int **p;//首先從 P開(kāi)始,先與*結(jié)合,說(shuō)明P是一個(gè)指針,然后再與*結(jié)合,說(shuō)明指針?biāo)赶虻脑厥侵羔?然后再與 int結(jié)合,說(shuō)明該指針?biāo)赶虻脑厥钦蛿?shù)據(jù).所以P是一個(gè)返回指向整型數(shù)據(jù)的指針的指針

      int p(int);//從P處起,先與()結(jié)合,說(shuō)明P是一個(gè)函數(shù),然后進(jìn)入()里分析,說(shuō)明該函數(shù)有一個(gè)整型變量的參數(shù)然后再與外面的int 結(jié)合,說(shuō)明函數(shù)的返回值是一個(gè)整型數(shù)據(jù).所以P是一個(gè)有整型參數(shù)且返回類型為整型的函數(shù)

      int(*p)(int);//從P處開(kāi)始,先與指針結(jié)合,說(shuō)明P是一個(gè)指針,然后與()結(jié)合,說(shuō)明指針指向的是一個(gè)函數(shù),然后再與()里的int 結(jié)合,說(shuō)明函數(shù)有一個(gè)int 型的參數(shù),再與最外層的int 結(jié)合,說(shuō)明函數(shù)的返回類型是整型,所以P是一個(gè)指向有一個(gè)整型參數(shù)且返回類型為整型的函數(shù)的指針

      int *(*p(int))[3];//從 P開(kāi)始,先與()結(jié)合,說(shuō)明P是一個(gè)函數(shù),然后進(jìn)入()里面,與int結(jié)合,說(shuō)明函數(shù)有一個(gè)整型變量參數(shù),然后再與外面的*結(jié)合,說(shuō)明函數(shù)返回的是一個(gè)指針,然后到最外面一層,先與[]結(jié)合,說(shuō)明返回的指針指向的是一個(gè)數(shù)組,然后再與*結(jié)合,說(shuō)明數(shù)組里的元素是指針,然后再與int 結(jié)合,說(shuō)明指針指向的內(nèi)容是整型數(shù)據(jù).所以P是一個(gè)參數(shù)為一個(gè)整數(shù)且返回一個(gè)指向由整型指針變量組成的數(shù)組的指針變量的函數(shù) 2.指針?lè)治?/p>

      指針是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。要搞清一個(gè)指針需要搞清指針的四方面的內(nèi)容:指針的類型、指針?biāo)赶虻念愋?、指針的值或者叫指針?biāo)赶虻膬?nèi)存區(qū)、指針本身所占據(jù)的內(nèi)存區(qū)。

      指針的類型:把指針聲明語(yǔ)句里的指針名字去掉,剩下的部分就是這個(gè)指針的類型

      指針?biāo)赶虻念愋停喊阎羔樎暶髡Z(yǔ)句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針?biāo)赶虻念愋停ㄔ谥羔樀乃阈g(shù)運(yùn)算中,指針?biāo)赶虻念愋陀泻艽蟮淖饔茫?/p>

      指針?biāo)赶虻膬?nèi)存區(qū):從指針的值所代表的那個(gè)內(nèi)存地址開(kāi)始,長(zhǎng)度為sizeof(指針?biāo)赶虻念愋?的一片內(nèi)存區(qū)。(一個(gè)指針指向了某塊內(nèi)存區(qū)域,就相當(dāng)于說(shuō)該指針的值是這塊內(nèi)存區(qū)域的首地址)指針本身所占據(jù)的內(nèi)存區(qū):用函數(shù)sizeof(指針的類型)可以測(cè)出指針本身所占據(jù)的內(nèi)存區(qū)(在 32位平臺(tái)里,指針本身占據(jù)了 4個(gè)字節(jié)的長(zhǎng)度)3.指針的算術(shù)運(yùn)算

      指針和整數(shù)進(jìn)行加減:一個(gè)指針 ptrold加(減)一個(gè)整數(shù) n后,結(jié)果是一個(gè)新的指針ptrnew,ptrnew 的類型和 ptrold 的類型相同,ptrnew 所指向的類型和 ptrold所指向的類型也相同,ptrnew的值將比 ptrold 的值增加(減少)了n乘sizeof(ptrold所指向的類型)個(gè)字節(jié)。

      指針和指針進(jìn)行加減:兩個(gè)指針不能進(jìn)行加法運(yùn)算,這是非法操作;兩個(gè)指針可以進(jìn)行減法操作,但必須類型相同,一般用在數(shù)組方面。4.運(yùn)算符&和*

      &是取地址運(yùn)算符,*是間接運(yùn)算符。

      &a的運(yùn)算結(jié)果是一個(gè)指針,指針的類型是a的類型加個(gè)*,指針?biāo)赶虻念愋褪莂的類型,指針?biāo)赶虻牡刂仿?,那就是a的地址。

      *p的運(yùn)算結(jié)果就五花八門(mén)了,總之*p 的結(jié)果是 p 所指向的東西,這個(gè)東西有這些特點(diǎn):它的類型是 p指向的類型,它所占用的地址是p所指向的地址。5.數(shù)組和指針的關(guān)系

      數(shù)組的數(shù)組名其實(shí)可以看作一個(gè)指針。

      聲明了一個(gè)數(shù)組 TYPE array[n],則數(shù)組名稱array就有了兩重含義: 第一,它代表整個(gè)數(shù)組,它的類型是 TYPE[n];

      第二,它是一個(gè)常量指針,該指針的類型是TYPE*,該指針指向的類型是 TYPE,也就是數(shù)組單元的類型,該指針指向的內(nèi)存區(qū)就是數(shù)組第0號(hào)單元,該指針自己占有單獨(dú)的內(nèi)存區(qū),注意它和數(shù)組第0號(hào)單元占據(jù)的內(nèi)存區(qū)是不同的。該指針的值是不能修改的,即類似 array++的表達(dá)式是錯(cuò)誤的。6.指針和結(jié)構(gòu)類型的關(guān)系

      假設(shè)我們定義了一個(gè)結(jié)構(gòu)體,struct MyStruct{inta;int b;int c;};同時(shí)定義結(jié)構(gòu)體的結(jié)構(gòu)對(duì)象并初始化,struct MyStructss={20,30,40};那么我們?nèi)绾瓮ㄟ^(guò)指針ptr 來(lái)訪問(wèn) ss的三個(gè)成員變量呢?

      答案就是,我們先定義一個(gè)指向結(jié)構(gòu)對(duì)象 ss的指針,struct MyStruct *ptr=&ss;然后,使用指向運(yùn)算符->便可實(shí)現(xiàn)對(duì)結(jié)構(gòu)對(duì)象ss成員的訪問(wèn)。ptr->a;//或者可以這們(*ptr).a,建議使用前者 ptr->b;ptr->c;

      7.指針和函數(shù)的關(guān)系

      可以把一個(gè)指針聲明成為一個(gè)指向函數(shù)的指針,從而通過(guò)函數(shù)指針調(diào)用函數(shù)。讓我們舉一個(gè)例子來(lái)說(shuō)明以下吧。

      int fun(char *,int);int(*pfun)(char *,int);pfun=fun;

      int a=(*pfun)(“abcdefg”,7);

      例中,定義了一個(gè)指向函數(shù)fun的指針pfun,把pfun作為函數(shù)的形參。把指針表達(dá)式作為實(shí)參,從而實(shí)現(xiàn)了對(duì)函數(shù)fun的調(diào)用。8.指針類型轉(zhuǎn)換

      當(dāng)我們初始化一個(gè)指針或給一個(gè)指針賦值時(shí),賦值號(hào)的左邊是一個(gè)指針,賦值號(hào)的右邊是一個(gè)指針表達(dá)式,這就要求兩邊的類型一致,所指向的類型也一致,如果不一致的話,需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。語(yǔ)法格式是:(TYPE *)p;

      這樣強(qiáng)制類型轉(zhuǎn)換的結(jié)果是一個(gè)新指針,該新指針的類型是TYPE *,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。要注意的是,原來(lái)的指針p的一切屬性都沒(méi)有被修改。

      另外,一個(gè)函數(shù)如果使用了指針作為形參,那么在函數(shù)調(diào)用語(yǔ)句的實(shí)參和形參的結(jié)合過(guò)程中,也必須保證類型一致,否則需要強(qiáng)制轉(zhuǎn)換。

      第四篇:android智能指針(wp、sp)學(xué)習(xí)總結(jié)

      智能指針:強(qiáng)指針sp,弱指針wp,輕量級(jí)指針LightRefBase。

      相關(guān)文件:RefBase.h,RefBase.cpp,StrongPointer.h(注:參考代碼android 4.2.2)。RefBase.h:定義了RefBase類定義,wp模板類定義和實(shí)現(xiàn),以及LightRefBase類定義。RefBase.cpp:定義了RefBase類實(shí)現(xiàn)以及RefBase的嵌套類weakref_type的實(shí)現(xiàn)。StrongPointer.h:定義了sp模板類定義和實(shí)現(xiàn)。RefBase類主要方法如下:

      void RefBase::incStrong(const void* id)const {

      weakref_impl* const refs = mRefs;

      refs->incWeak(id);// 增加一次弱引用計(jì)數(shù)

      refs->addStrongRef(id);// 空函數(shù)

      // 原子操作,增加一次強(qiáng)引用計(jì)數(shù),返回的是refs->mStrong執(zhí)行加1操作之前的值 const int32_t c = android_atomic_inc(&refs->mStrong);

      ALOG_ASSERT(c > 0, “incStrong()called on %p after last strong ref”, refs);// 第一次執(zhí)行,c的值為INITIAL_STRONG_VALUE if(c!= INITIAL_STRONG_VALUE){ //從第二次開(kāi)始執(zhí)行后,此條件都成立,直接返回

      return;

      }

      // 執(zhí)行操作,refs->mStrong +(-INITIAL_STRONG_VALUE),第一次執(zhí)行后強(qiáng)引用計(jì)數(shù)refs->mStrong值變?yōu)?

      android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);

      refs->mBase->onFirstRef();//第一次執(zhí)行會(huì)調(diào)用該方法,子類可以覆蓋該方法。}

      void RefBase::decStrong(const void* id)const {

      weakref_impl* const refs = mRefs;refs->removeStrongRef(id);// 空函數(shù)

      // 原子操作,強(qiáng)引用計(jì)數(shù)減1,返回的是執(zhí)行減1操作之前的值 const int32_t c = android_atomic_dec(&refs->mStrong);

      ALOG_ASSERT(c >= 1, “decStrong()called on %p too many times”, refs);

      if(c == 1){

      refs->mBase->onLastStrongRef(id);// 子類可覆蓋該方法

      // mFlags值缺省為0

      if((refs->mFlags&OBJECT_LIFETIME_MASK)== OBJECT_LIFETIME_STRONG)

      {

      delete this;

      }

      }

      refs->decWeak(id);// 弱引用計(jì)數(shù)減1 }

      void RefBase::forceIncStrong(const void* id)const {

      weakref_impl* const refs = mRefs;

      refs->incWeak(id);// 弱引用計(jì)數(shù)加1

      refs->addStrongRef(id);// 空函數(shù)

      const int32_t c = android_atomic_inc(&refs->mStrong);// 強(qiáng)引用計(jì)數(shù)加1

      ALOG_ASSERT(c >= 0, “forceIncStrong called on %p after ref count underflow”,refs);

      switch(c){

      case INITIAL_STRONG_VALUE:

      android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);// 強(qiáng)引用計(jì)數(shù)減INITIAL_STRONG_VALUE

      // fall through...case 0:

      refs->mBase->onFirstRef();

      } } // 創(chuàng)建嵌套類對(duì)象

      RefBase::weakref_type* RefBase::createWeak(const void* id)const {

      mRefs->incWeak(id);// 弱引用計(jì)數(shù)加1

      return mRefs;}

      // 延長(zhǎng)對(duì)象生命周期

      void RefBase::extendObjectLifetime(int32_t mode){

      android_atomic_or(mode, &mRefs->mFlags);// 修改mFlags的值為mode }

      // RefBase構(gòu)造函數(shù)在實(shí)例化時(shí),創(chuàng)建一個(gè)weakref_impl對(duì)象,并且將當(dāng)前類對(duì)象的this指針作為參數(shù)傳遞給weakref_impl類構(gòu)造函數(shù),因此它們之間存在相互引用。RefBase::RefBase()

      : mRefs(new weakref_impl(this)){ }

      RefBase::~RefBase(){

      if(mRefs->mStrong == INITIAL_STRONG_VALUE){

      delete mRefs;

      } else {

      if((mRefs->mFlags & OBJECT_LIFETIME_MASK)!= OBJECT_LIFETIME_STRONG){

      if(mRefs->mWeak == 0){

      delete mRefs;

      }

      }

      }

      const_cast(mRefs)= NULL;}

      weakref_type類主要方法如下:

      //由弱生強(qiáng)方法,例如A * pa =new A();wp wpa(pa);sp spa = wpa.promote();bool RefBase::weakref_type::attemptIncStrong(const void* id){

      incWeak(id);// 弱引用計(jì)數(shù)加1

      weakref_impl* const impl = static_cast(this);

      int32_t curCount = impl->mStrong;// 強(qiáng)引用計(jì)數(shù),初始值為INITIAL_STRONG_VALUE

      ALOG_ASSERT(curCount >= 0, “attemptIncStrong called on %p after underflow”,this);// while循環(huán)表示多線程操作情況,將強(qiáng)引用計(jì)數(shù)加1

      while(curCount > 0 && curCount!= INITIAL_STRONG_VALUE){

      if(android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong)== 0){

      break;

      }

      curCount = impl->mStrong;

      }

      if(curCount <= 0 || curCount == INITIAL_STRONG_VALUE){

      bool allow;

      // 判斷是否可以增加強(qiáng)引用計(jì)數(shù)

      if(curCount == INITIAL_STRONG_VALUE){

      allow=(impl->mFlags&OBJECT_LIFETIME_WEAK)!= OBJECT_LIFETIME_WEAK

      || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);

      } else {

      // Attempting to revive the object...this is allowed

      // if the object DOES have a longer lifetime(so we can safely

      // call the object with only a weak ref)and the implementation

      // allows it to happen.allow =(impl->mFlags&OBJECT_LIFETIME_WEAK)== OBJECT_LIFETIME_WEAK

      && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);

      }

      // 若不能增加強(qiáng)引用計(jì)數(shù),就執(zhí)行弱引用計(jì)數(shù)減1,因?yàn)橹叭跻米鲞^(guò)加1了。

      if(!allow){

      decWeak(id);

      return false;

      }

      curCount = android_atomic_inc(&impl->mStrong);// 強(qiáng)引用計(jì)數(shù)加1

      if(curCount > 0 && curCount < INITIAL_STRONG_VALUE){

      impl->mBase->onLastStrongRef(id);

      }

      }

      impl->addStrongRef(id);// 空函數(shù)

      if(curCount == INITIAL_STRONG_VALUE){ // 將impl->mStrong的值+(-INITIAL_STRONG_VALUE)

      android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);

      impl->mBase->onFirstRef();// 第一次執(zhí)行強(qiáng)引用計(jì)數(shù)加1,調(diào)用此方法

      }

      return true;}

      void RefBase::weakref_type::incWeak(const void* id){

      //基類指針轉(zhuǎn)換為子類指針,weakref_impl為weakref_type的子類。

      weakref_impl* const impl = static_cast(this);

      impl->addWeakRef(id);//空函數(shù)

      const int32_t c = android_atomic_inc(&impl->mWeak);// 弱引用計(jì)數(shù)加1

      ALOG_ASSERT(c >= 0, “incWeak called on %p after last weak ref”, this);}

      void RefBase::weakref_type::decWeak(const void* id){

      weakref_impl* const impl = static_cast(this);

      impl->removeWeakRef(id);// 空函數(shù)

      const int32_t c = android_atomic_dec(&impl->mWeak);// 弱引用計(jì)數(shù)減1

      ALOG_ASSERT(c >= 1, “decWeak called on %p too many times”, this);

      if(c!= 1)return;

      if((impl->mFlags&OBJECT_LIFETIME_WEAK)== OBJECT_LIFETIME_STRONG){

      if(impl->mStrong == INITIAL_STRONG_VALUE){

      delete impl->mBase;//delete 實(shí)際對(duì)象

      } else {

      delete impl;//delete weakref_impl對(duì)象

      }

      } else {

      // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}

      impl->mBase->onLastWeakRef(id);

      if((impl->mFlags&OBJECT_LIFETIME_MASK)== OBJECT_LIFETIME_WEAK){

      delete impl->mBase;//delete 實(shí)際對(duì)象

      }

      } }

      總結(jié):

      wp和sp使用實(shí)例代碼如下: { Class A : public RefBase{};A *p = new A;sp pa(p);wp pb(pa);} sp: 它是一個(gè)模板類,強(qiáng)指針,采用代理模式實(shí)現(xiàn),控制實(shí)際對(duì)象(通過(guò)模板參數(shù)實(shí)例化)的生命周期結(jié)束。sp中只有一個(gè)成員變量m_ptr指向?qū)嶋H對(duì)象。上述實(shí)際對(duì)象必須是RefBase的子類對(duì)象。

      sp對(duì)象被構(gòu)造時(shí),在其構(gòu)造函數(shù)中調(diào)用m_ptr->incStrong(this);使強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)加1;sp對(duì)象被析構(gòu)時(shí),在其析構(gòu)函數(shù)中調(diào)用m_ptr->decStrong(this);使強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)都減1。

      wp: 它是一個(gè)模板類,弱指針,采用代理模式實(shí)現(xiàn),控制實(shí)際對(duì)象(通過(guò)模板參數(shù)實(shí)例化)的生命周期結(jié)束。上述實(shí)際對(duì)象必須是RefBase的子類對(duì)象。

      wp中有兩個(gè)成員變量:m_ptr指向?qū)嶋H對(duì)象,m_refs指向嵌套類(weakref_impl)對(duì)象。

      wp對(duì)象被構(gòu)造時(shí),在其構(gòu)造函數(shù)中調(diào)用 m_refs = m_ptr->createWeak(this);使弱引用計(jì)數(shù)加1;wp對(duì)象被析構(gòu)時(shí),在其析構(gòu)函數(shù)中調(diào)用m_refs->decWeak(this),使弱引用計(jì)數(shù)減1。

      weakref_impl:繼承自RefBase::weakref_type,在該類中定義了幾個(gè)重要的成員變量,volatile int32_t

      mStrong;// 強(qiáng)引用計(jì)數(shù),初始值為INITIAL_STRONG_VALUE volatile int32_t

      mWeak;// 弱引用計(jì)數(shù),初始值為0 RefBase* const

      mBase;// 指向?qū)嶋H對(duì)象指針

      volatile int32_t

      mFlags;// 標(biāo)識(shí),設(shè)置對(duì)象生命周期,初始值為0.mFlags實(shí)際上可取下面三種值:

      OBJECT_LIFETIME_STRONG = 0x0000, OBJECT_LIFETIME_WEAK

      = 0x0001, OBJECT_LIFETIME_MASK

      = 0x0001。

      通過(guò)調(diào)用RefBase::extendObjectLifetime()方法可以修改結(jié)束對(duì)象的生命周期時(shí)機(jī),例如在上面代碼:RefBase::decStrong(),RefBase::~RefBase(),RefBase::weakref_type::incWeak()等方法都有根據(jù)mFlags的值來(lái)確定是否結(jié)束類對(duì)象的生命周期。

      在類weakref_impl中,強(qiáng)引用計(jì)數(shù)控制實(shí)際對(duì)象的生命周期,弱引用計(jì)數(shù)控制weakref_impl對(duì)象自己的生命周期。在缺省情況下(mFlags為0),強(qiáng)引用計(jì)數(shù)為0,會(huì)結(jié)束實(shí)際對(duì)象的生命周期,弱引用計(jì)數(shù)為0,會(huì)結(jié)束weakref_impl對(duì)象自己的生命周期。

      第五篇:C語(yǔ)言實(shí)驗(yàn)程序、總結(jié) 實(shí)驗(yàn)七 指針

      一 實(shí)驗(yàn)?zāi)康?/p>

      實(shí)驗(yàn)七 指針 了解指針的概念,學(xué)會(huì)定義和使用指針變量。2 掌握指針、變量和數(shù)組的關(guān)系及使用方法。3 學(xué)會(huì)使用指向函數(shù)的指針變量。

      二 實(shí)驗(yàn)內(nèi)容 編寫(xiě)函數(shù)fun(float *sn,int n),其功能是:根據(jù)以下公式計(jì)算s,計(jì)算結(jié)果通過(guò)形參sn傳回;n通過(guò)實(shí)參傳入,n的值大于等于0。上機(jī)運(yùn)行并記錄輸入輸出(主函數(shù)已給出)。

      s?1?1111 ????3572n?1fun(float *sn,int n){ 定義變量:和s,通項(xiàng)w,符號(hào)f,循環(huán)控制變量i; /* 其中s、f要初始化 */ 循環(huán)求累加和s { 改變符號(hào);/* 由負(fù)變正或由正變負(fù) */ 求通項(xiàng)w;累加:s+=w;} 形參指針變量sn賦值;/* 通過(guò)形參sn傳回累加和s */ } main(){ float s;int n;printf(“n=”);scanf(“%d”,&n);fun(&s,n);printf(“s=%fn”,s);}

      完整程序如下:

      #include void fun(float *sn,int n){ float s=0.0,w,f=-1.0;int i=0;for(i=0;i<=n;i++);{ f=(-1)*f;w=f/(2*i+1);s+=w;} *sn =s;} main(){ float s;int n;printf(“n=”);scanf(“%d”,&n);fun(&s,n);printf(“s=%fn”,s);}

      輸出結(jié)果如下圖: 想使指針變量pt1指向a和b中的大者,pt2指向小者,以下程序能否實(shí)現(xiàn)此目的? swap(int *p1,int *p2){ int *p;p=p1;p1=p2;p2=p } main(){ int a,b;int *pt1,*pt2;scanf(“%d,%d”,&a,&b);pt1=&a;pt2=&b;if(a

      上機(jī)調(diào)試此程序。如果不能實(shí)現(xiàn)題目要求,指出原因并修改之。

      子函數(shù)swap改成下面程序方可實(shí)現(xiàn)目的,主函數(shù)不變: swap(int *p1,int *p2){ int p;p=*p1;*p1=*p2;*p2=p;} 下面的程序用來(lái)實(shí)現(xiàn)將一個(gè)3×3的矩陣轉(zhuǎn)置。#include void tranf(int(*p)[3]){ int t,i,j;for(i=0;i<3;i++)for(j=0;j

      程序修改如下: #include void tranf(int(*p)[N]){ int t,i,j;for(i=0;i<3;i++)for(j=0;j char *strc(char *s1,char *s2){ char *p=s1;while(*s2!='