久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

關于指針的一些總結

時間:2019-05-13 03:28:05下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關的《關于指針的一些總結》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《關于指針的一些總結》。

第一篇:關于指針的一些總結

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

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

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

constint*p;

intconst*q;

int*constr=&i;

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

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

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

大致說來其可分為三種情況:const修飾指針,const修飾引用,const修飾指針的引用.1.const修飾指針

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

const修飾指針本身

const修飾指針所指的變量(或對象)

const修飾指針本身和指針所指的變量(或對象)

(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并沒有限定是常量,可變

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

(2).const修飾指針指向的變量(或對象)

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

constint*pi=&a;

//orintconst*pi=&a;

//兩者毫無二致,不過BS喜歡前者,這也沒什么技術上的優劣之分,也就是說constint與intconst可以互換.建議大家熟

//悉這兩種形式,為簡潔便,以后統統用前者.//ok,const并不修飾指針本身,pi對賦值類型

//沒要求,但pi是int*型指針,所以所賦的必須是個地址值。

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

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

(3)const修飾指針本身和指針所指的變量(或對象)

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

constint*constpi=&a;

//orintconst*constpi=&a;

//將constpi看作一體,就與(2)所述相同,只是要求pi必須為const,正如上所說,=號兩邊的類型不必嚴格匹配,但必須含有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,=號右邊的變量(或對象)與所修飾的變量無關

a--;//error,a為const

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

這種情況比較簡單,沒有象修飾指針那樣繁復,因為引用和引用對象是一體的,所以引用被const修飾只有一種類型。

const修飾引用,引用本身不可變,但引用的變量(或對象)可以改變.例如:

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

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

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

i++;//ok,=右邊的變量與引用無關

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

i=j;//ok,=右邊的變量與引用無關

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

3.const修飾指針的引用

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

(1)

先給個例子:

constint*pi=&a;

constint*&ri=pi;

//orintconst*&ri=pi;

引用是引用對象的別名,正因為如此,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)的區別.(2)

用例子說明:

int*const&ri=&i;

去掉ri左邊的&號,則為int*constri,因為ri是別名,故ri的類型應與賦值的數類型一致,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)

用例子說明:

constint*pi=&j;

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

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

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

ri++;//error

*ri=6;//error

第二篇:指針概念知識點總結--經典

指針概念知識點

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

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

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

● 通常指針變量可以通過以下幾種方法獲得地址:通過地址運算“&”賦值,指針變量的初始化,通過其他指針變量賦值,用NULL給指針變量賦空值,以及通過調用標準函數賦值。

● “*”稱為指針運算符(單目運算符),也稱取內容運算符。當指針變量p指向一個變量x時,可以用*p的形式存取該變量的值。此時,*p與變量x相互等價。

● 取地址運算符“&”與指針運算符“*”作用在一起時,有相互“抵消”的作用。對于變量x,*&x與x相互等價。

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

● 未對指針變量p賦值即p沒有指向時,而就對*p賦值,該值就代替了內存中某單元的內容,有可能出現不可意料的錯誤。

● 一個數組的元素在內存中是連續存放的,數組第一個元素的地址稱數組的首地址。在C語言中,數組名是該數組的首地址,因此,數組名是指針常量。

● 當指針變量p指向數組元素時,p加上一個正整數n,則當前指向為相對p向前移動n個元素的位置;p減去一個正整數n,則當前指向為相對p向后移動n個元素的位置。

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

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

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

● C語言的二維數組由若干個一維數組構成。若有定義語句:int a[M][N], i, j;,則以下元素的七種表示相互等價: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)。

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

● 除了由二維字符數組可以構成字符串數組外,還可以定義一個指針數組,并在定義時用字符串賦初值的方法,構成一個字符串數組。

● 指向指針的指針變量,經過二次間接存取后才能存取到變量的值。

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

● 當指針變量指向某一結構體變量時,可用下述三種方式之一存取結構體成員(三種方式是等價的):結構體變量名.成員名、指針變量名->成員名、(*指針變量名).成員名。

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

第三篇:史上最全C語言指針總結

C語言中的精華是什么,答曰指針,這也是C語言中唯一的難點。

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

本文將從八個常見的方面來透視C語言中的指針,當然,還有其他沒有具體提到的方面,像指針表達式、指針安全等問題,以后有機會我再慢慢補充。

還是那句老話,重要的是實踐,多寫代碼,才是學好C語言的關鍵。1.指針類型分析

分析指針,可以從變量名處起,根據運算符優先級結合,一步一步分析.int p;//這是一個普通的整型變量

int *p;//首先從P處開始,先與*結合,所以說明P是一個指針,然后再與int結合,說明指針所指向的內容的類型為int 型.所以 P是一個返回整型數據的指針

int p[3];//首先從P處開始,先與[]結合,說明P 是一個數組,然后與int結合,說明數組里的元素是整型的,所以 P是一個由整型數據組成的數組

int *p[3];//首先從P處開始,先與[]結合,因為其優先級比*高,所以P是一個數組,然后再與*結合,說明數組里的元素是指針類型,然后再與 int結合,說明指針所指向的內容的類型是整型的,所以是一個由返回整型數據的指針所組成的數組

int(*p)[3];//首先從P處開始,先與*結合,說明P是一個指針然后再與[]結合(與“()”這步可以忽略,只是為了改變優先級),說明指針所指向的內容是一個數組,然后再與int 結合,說明數組里的元素是整型的.所以P是一個指向由整型數據組成的數組的指針

int **p;//首先從 P開始,先與*結合,說明P是一個指針,然后再與*結合,說明指針所指向的元素是指針,然后再與 int結合,說明該指針所指向的元素是整型數據.所以P是一個返回指向整型數據的指針的指針

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

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

int *(*p(int))[3];//從 P開始,先與()結合,說明P是一個函數,然后進入()里面,與int結合,說明函數有一個整型變量參數,然后再與外面的*結合,說明函數返回的是一個指針,然后到最外面一層,先與[]結合,說明返回的指針指向的是一個數組,然后再與*結合,說明數組里的元素是指針,然后再與int 結合,說明指針指向的內容是整型數據.所以P是一個參數為一個整數且返回一個指向由整型指針變量組成的數組的指針變量的函數 2.指針分析

指針是一個特殊的變量,它里面存儲的數值被解釋成為內存里的一個地址。要搞清一個指針需要搞清指針的四方面的內容:指針的類型、指針所指向的類型、指針的值或者叫指針所指向的內存區、指針本身所占據的內存區。

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

指針所指向的類型:把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型(在指針的算術運算中,指針所指向的類型有很大的作用)

指針所指向的內存區:從指針的值所代表的那個內存地址開始,長度為sizeof(指針所指向的類型)的一片內存區。(一個指針指向了某塊內存區域,就相當于說該指針的值是這塊內存區域的首地址)指針本身所占據的內存區:用函數sizeof(指針的類型)可以測出指針本身所占據的內存區(在 32位平臺里,指針本身占據了 4個字節的長度)3.指針的算術運算

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

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

&是取地址運算符,*是間接運算符。

&a的運算結果是一個指針,指針的類型是a的類型加個*,指針所指向的類型是a的類型,指針所指向的地址嘛,那就是a的地址。

*p的運算結果就五花八門了,總之*p 的結果是 p 所指向的東西,這個東西有這些特點:它的類型是 p指向的類型,它所占用的地址是p所指向的地址。5.數組和指針的關系

數組的數組名其實可以看作一個指針。

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

第二,它是一個常量指針,該指針的類型是TYPE*,該指針指向的類型是 TYPE,也就是數組單元的類型,該指針指向的內存區就是數組第0號單元,該指針自己占有單獨的內存區,注意它和數組第0號單元占據的內存區是不同的。該指針的值是不能修改的,即類似 array++的表達式是錯誤的。6.指針和結構類型的關系

假設我們定義了一個結構體,struct MyStruct{inta;int b;int c;};同時定義結構體的結構對象并初始化,struct MyStructss={20,30,40};那么我們如何通過指針ptr 來訪問 ss的三個成員變量呢?

答案就是,我們先定義一個指向結構對象 ss的指針,struct MyStruct *ptr=&ss;然后,使用指向運算符->便可實現對結構對象ss成員的訪問。ptr->a;//或者可以這們(*ptr).a,建議使用前者 ptr->b;ptr->c;

7.指針和函數的關系

可以把一個指針聲明成為一個指向函數的指針,從而通過函數指針調用函數。讓我們舉一個例子來說明以下吧。

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

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

例中,定義了一個指向函數fun的指針pfun,把pfun作為函數的形參。把指針表達式作為實參,從而實現了對函數fun的調用。8.指針類型轉換

當我們初始化一個指針或給一個指針賦值時,賦值號的左邊是一個指針,賦值號的右邊是一個指針表達式,這就要求兩邊的類型一致,所指向的類型也一致,如果不一致的話,需要進行強制類型轉換。語法格式是:(TYPE *)p;

這樣強制類型轉換的結果是一個新指針,該新指針的類型是TYPE *,它指向的類型是TYPE,它指向的地址就是原指針指向的地址。要注意的是,原來的指針p的一切屬性都沒有被修改。

另外,一個函數如果使用了指針作為形參,那么在函數調用語句的實參和形參的結合過程中,也必須保證類型一致,否則需要強制轉換。

第四篇:android智能指針(wp、sp)學習總結

智能指針:強指針sp,弱指針wp,輕量級指針LightRefBase。

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

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

weakref_impl* const refs = mRefs;

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

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

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

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

return;

}

// 執行操作,refs->mStrong +(-INITIAL_STRONG_VALUE),第一次執行后強引用計數refs->mStrong值變為1

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

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

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

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

// 原子操作,強引用計數減1,返回的是執行減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);// 弱引用計數減1 }

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

weakref_impl* const refs = mRefs;

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

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

const int32_t c = android_atomic_inc(&refs->mStrong);// 強引用計數加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);// 強引用計數減INITIAL_STRONG_VALUE

// fall through...case 0:

refs->mBase->onFirstRef();

} } // 創建嵌套類對象

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

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

return mRefs;}

// 延長對象生命周期

void RefBase::extendObjectLifetime(int32_t mode){

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

// RefBase構造函數在實例化時,創建一個weakref_impl對象,并且將當前類對象的this指針作為參數傳遞給weakref_impl類構造函數,因此它們之間存在相互引用。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類主要方法如下:

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

incWeak(id);// 弱引用計數加1

weakref_impl* const impl = static_cast(this);

int32_t curCount = impl->mStrong;// 強引用計數,初始值為INITIAL_STRONG_VALUE

ALOG_ASSERT(curCount >= 0, “attemptIncStrong called on %p after underflow”,this);// while循環表示多線程操作情況,將強引用計數加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;

// 判斷是否可以增加強引用計數

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);

}

// 若不能增加強引用計數,就執行弱引用計數減1,因為之前弱引用做過加1了。

if(!allow){

decWeak(id);

return false;

}

curCount = android_atomic_inc(&impl->mStrong);// 強引用計數加1

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

impl->mBase->onLastStrongRef(id);

}

}

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

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

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

impl->mBase->onFirstRef();// 第一次執行強引用計數加1,調用此方法

}

return true;}

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

//基類指針轉換為子類指針,weakref_impl為weakref_type的子類。

weakref_impl* const impl = static_cast(this);

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

const int32_t c = android_atomic_inc(&impl->mWeak);// 弱引用計數加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);// 空函數

const int32_t c = android_atomic_dec(&impl->mWeak);// 弱引用計數減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 實際對象

} else {

delete impl;//delete weakref_impl對象

}

} 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 實際對象

}

} }

總結:

wp和sp使用實例代碼如下: { Class A : public RefBase{};A *p = new A;sp pa(p);wp pb(pa);} sp: 它是一個模板類,強指針,采用代理模式實現,控制實際對象(通過模板參數實例化)的生命周期結束。sp中只有一個成員變量m_ptr指向實際對象。上述實際對象必須是RefBase的子類對象。

sp對象被構造時,在其構造函數中調用m_ptr->incStrong(this);使強引用計數和弱引用計數加1;sp對象被析構時,在其析構函數中調用m_ptr->decStrong(this);使強引用計數和弱引用計數都減1。

wp: 它是一個模板類,弱指針,采用代理模式實現,控制實際對象(通過模板參數實例化)的生命周期結束。上述實際對象必須是RefBase的子類對象。

wp中有兩個成員變量:m_ptr指向實際對象,m_refs指向嵌套類(weakref_impl)對象。

wp對象被構造時,在其構造函數中調用 m_refs = m_ptr->createWeak(this);使弱引用計數加1;wp對象被析構時,在其析構函數中調用m_refs->decWeak(this),使弱引用計數減1。

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

mStrong;// 強引用計數,初始值為INITIAL_STRONG_VALUE volatile int32_t

mWeak;// 弱引用計數,初始值為0 RefBase* const

mBase;// 指向實際對象指針

volatile int32_t

mFlags;// 標識,設置對象生命周期,初始值為0.mFlags實際上可取下面三種值:

OBJECT_LIFETIME_STRONG = 0x0000, OBJECT_LIFETIME_WEAK

= 0x0001, OBJECT_LIFETIME_MASK

= 0x0001。

通過調用RefBase::extendObjectLifetime()方法可以修改結束對象的生命周期時機,例如在上面代碼:RefBase::decStrong(),RefBase::~RefBase(),RefBase::weakref_type::incWeak()等方法都有根據mFlags的值來確定是否結束類對象的生命周期。

在類weakref_impl中,強引用計數控制實際對象的生命周期,弱引用計數控制weakref_impl對象自己的生命周期。在缺省情況下(mFlags為0),強引用計數為0,會結束實際對象的生命周期,弱引用計數為0,會結束weakref_impl對象自己的生命周期。

第五篇:C語言實驗程序、總結 實驗七 指針

一 實驗目的

實驗七 指針 了解指針的概念,學會定義和使用指針變量。2 掌握指針、變量和數組的關系及使用方法。3 學會使用指向函數的指針變量。

二 實驗內容 編寫函數fun(float *sn,int n),其功能是:根據以下公式計算s,計算結果通過形參sn傳回;n通過實參傳入,n的值大于等于0。上機運行并記錄輸入輸出(主函數已給出)。

s?1?1111 ????3572n?1fun(float *sn,int n){ 定義變量:和s,通項w,符號f,循環控制變量i; /* 其中s、f要初始化 */ 循環求累加和s { 改變符號;/* 由負變正或由正變負 */ 求通項w;累加:s+=w;} 形參指針變量sn賦值;/* 通過形參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);}

輸出結果如下圖: 想使指針變量pt1指向a和b中的大者,pt2指向小者,以下程序能否實現此目的? 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

上機調試此程序。如果不能實現題目要求,指出原因并修改之。

子函數swap改成下面程序方可實現目的,主函數不變: swap(int *p1,int *p2){ int p;p=*p1;*p1=*p2;*p2=p;} 下面的程序用來實現將一個3×3的矩陣轉置。#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!='

主站蜘蛛池模板: 麻花传媒68xxx在线观看| 男女一边摸一边做爽爽| 亚洲乱亚洲乱妇小说网| 99久re热视频这只有精品6| 四川丰满少妇被弄到高潮| 亚洲一区二区三区av无码| 纯爱无遮挡h肉动漫在线播放| 亚洲国产综合人成综合网站| 国产精品久久久久久亚洲影视内衣| 忘忧草社区www日本高清图片| 日韩精品一卡二卡二卡四卡乱码| 八区精品色欲人妻综合网| 香蕉成人伊视频在线观看| 亚洲性无码一区二区三区| 猫咪av成人永久网站在线观看| 久久久精品2019免费观看| 精品少妇爆乳无码aⅴ区| 在线视频 一区 色| 97久久精品人人澡人人爽| 2023极品少妇xxxo露脸| 亚洲色欲或者高潮影院| 日本高清在线一区二区三区| 国产精品9999久久久久| 免费网禁国产you女网站下载| 午夜无码片在线观看影视| 青青草国产精品一区二区| 9999国产精品欧美久久久久久| 免费人成视频在线播放| 中文无码伦av中文字幕| 国产亚洲美女精品久久久| 99久久国产热无码精品免费| 熟睡人妻被讨厌的公侵犯深田咏美| 久久久久久久岛国免费观看| 在线天堂中文www官网| 国产高清在线精品一区二区三区| 少妇高潮毛片色欲ava片| 国产精品无码免费视频二三区| 狠狠躁夜夜躁av网站中文字幕| 宅宅少妇无码| 国产内射一区亚洲| 国产一区二区三区四区精华|