关于指针的一些总结

时间: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!='')*p++=*s2++;return s1;} main(){ char s1[30]=“computer ok!”,s2[]=“language”,*pt;pt=strc(s1,s2);printf(“%sn”,pt);/* 第10行 */ } 将程序第10行中的%s改成%c,应该怎样修改?(只允许修改第10行)

应改为: printf(“%cn”,*pt++);

实验总结:本次实验主要掌握指针的概念,学会定义和使用指针变量,掌握指针、变量和数组的关系及使用方法,学会使用指向函数的指针变量,通过本次实验,很好的了解了指针的使用,加深了对指针的认识。

下载关于指针的一些总结word格式文档
下载关于指针的一些总结.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    C语言和C的指针学习总结

    C语言之指针、数组和函数基本解释1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。2、数组名对应着(而不是指向)一块内存,其......

    C++“指针”学习建议

    一.对于众多人提出的c/c++中指针难学的问题做个总结: 指针学习不好关键是概念不清造成的,说的简单点就是书没有认真看,指针的学习犹如人在学习饶口令不多看多学多练是不行的,下......

    2014年公司战略指针

    2014年公司战略指针 一、总体趋势: 1. 国家在上海自贸区实行“负面清单”管理,意味着将来所有企业有可能不再 被“经营范围”所困,更多地参与现在垄断或特行管理行业的竞争; 2.......

    C语言指针实习

    实习七:指针实习一、实习目的 姓名:尹思智学号:2012014413 完成日期:2013年4月 1. 由键盘输入10个整数,将它们从小到大排序 2. 将10个字符串(设其长度小于30)排序。 3. 找出二维数......

    C语言实验报告《指针》

    学号:__________ 姓名:__________ 班级:__________ 日期:__________ 指导教师:__________ 成绩:__________实验五 指针一、实验目的1、掌握指针的概念、会定义和使用指针变量2、掌......

    磁电式指针万用表原理与维修总结

    磁电式指针万用表维修总结 MF-47型指针万用表原理与维修经验总结 指针系仪表分为磁电式和电磁式两种,现在的指针万用表都是以磁电式仪表为主,由于电磁式仪表灵敏度较低,所以......

    新形势下反腐倡廉思想指针上

    新形势下反腐倡廉的思想指针(上) 1、 正确 切实抓好反腐倡廉制度建设必须不断提高制度执行力。 2、利用和操纵引资项目、资产重组项目,为本人或者特定关系人谋取私利,可能构成受......

    水表指针识别大作业最终报告

    水表指针识别大作业最终报告 摘 要:由于读表过程中存在误差和错误,造成水表读数不准确,在水表图像处 理中及读数作了详细的讲述。而图像边缘检测是本次大作业的重点,着 重讲解了......