C++“指针”学习建议.pdf
《C++“指针”学习建议.pdf》由会员分享,可在线阅读,更多相关《C++“指针”学习建议.pdf(32页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、一.对于众多人提出的c/c+中指针难学的问题做个总结:指针学习不好关键是概念不清造成的,说的简单点就是书没有认真看,指针的学习犹如人在学习饶口令不多看多学多练是不行的,下面是两个很经典的例子,很多书上都有,对于学习的重点在于理解*x 和 x 的理解,他们并不相同,*x所表示的其实就是变量a 本身,x 表示的是变量 a在内存中的地址,如果想明白可以输出观察cout*x|x;,当定义了 int*x;后对 x=&a的理解的问题。仔细阅读和联系下面的两个例子我想指针问题就不是难点了!#include main()int a,b;/*定义 a,b 两个整形变量用于输入两个整数*/int *point_1
2、,*point_2,*temp_point;/*定义三个指针变量 */scanf(%d,%d,&a,&b);/*格式化输入 a,b 的值 */point_1=&a;/*把指针变量 point_1 的值指向变量a的地址 */point_2=&b;/*把指针变量 point_2 的值指向变量b的地址 */if (ab)temp_point=point_1;/*这里的 temp_point 是用于临时存储point_1 的值也就是变量a的地址的 */point_1=point_2;/*把 point_2 的值赋予 point_1*/point_2=temp_point;/*由于 point_1 的值
3、已经改变无法找到,利用前面临时存储的也就是temp_point 找回原 point_1 的值赋予 point_2,打到把 point_1 和 point_2 值对换的目的*/printf(%d,%d,*point_1,*point_2);/*利用*point_1 和*point_2也就是分辨指向b和 a 的方法把值显示屏幕上*/*此题需要注意和了解是的此法并没有改变变量a,b 的值只是利用指针变量分别存储a和 b 的地址,然后再把那两个指针变量的值对换一下其实就是存储在指针变量里面a与 b的地址对换,在利用*point_1 和*point_2的方式把调换后的值显示出来这里的*point_1 实
4、际就是 a,此中算法并非真的改变a,b 的值,而是利用指针进行地址交换达到大小排序的目的.*/#include main()int a,b;/*定义 a,b 两个整形变量用于输入两个整数*/int *point_1,*point_2;/*定义三个指针变量 */scanf(%d,%d,&a,&b);/*格式化输入 a,b 的值 */point_1=&a;/*把指针变量 point_1 的值指向变量 a 的地址*/point_2=&b;/*把指针变量 point_2 的值指向变量 b 的地址*/compositor(point_1,point_2);/*调用自定义的排序涵数,把 a,b 的地址传递
5、给point_1 和 point_2*/printf(%d,%d,a,b);/*打印出 a,b 的值*/static compositor(p1,p2)int *p1,*p2;/*定义形式参数p1,p2 为指针变量 */int temp;/*建立临时存储变量 */if (*p1*p2)/*如果*p1QueryInterface(IID_SOMEINTERFACE,&p);此处,p是 SOMEINTERFACE类型的指针,所以&p便是指针的指针,在QueryInterface返回的时候,如果调用成功,则变量 p包含一个指向新的接口的指针。如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完
6、全是一回事。如果你象下面这样声明函数:void func1(MYCLASS*&pMyClass);pMyClass=new MYCLASS;,其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传p的地址&p,而是直接传p 本身:MYCLASS*p=NULL;func1(p);在调用之后,p 指向一个新的对象。一般来讲,引用的原理或多或少就象一个指针,从语法上看它就是一个普通变量。所以只要你碰到*&,就应该想到*。也就是说这个函数修改或可能修改调用者的指针,而调用者象普通变量一样传递这个指针,不使用地址操作符&。至于说什么场合要使用这种方法,我会说,极少。MFC 在其集
7、合类中用到了它-例如,CObList,它是一个 Cobjects指针列表。Class CObList:public Cobject ,/获取/修改指定位置的元素Cobject*&GetAt(POSITION position);Cobject*GetAt(POSITION position)const;这里有两个 GetAt 函数,功能都是获取给定位置的元素。区别何在呢?区别在于一个让你修改列表中的对象,另一个则不行。所以如果你写成下面这样:Cobject*pObj=mylist.GetAt(pos);则 pObj 是列表中某个对象的指针,如果接着改变pObj 的值:pObj=pSomeOth
8、erObj;这并改变不了在位置pos 处的对象地址,而仅仅是改变了变量pObj。但是,如果你写成下面这样:Cobject*&rpObj=mylist.GetAt(pos);现在,rpObj 是引用一个列表中的对象的指针,所以当改变rpObj 时,也会改变列表中位置pos 处的对象地址-换句话说,替代了这个对象。这就是为什么 CObList 会有两个 GetAt函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不是对象本身。这两个函数都可以修改对象,但只有*&版本可以替代对象。在 C/C+中引用是很重要的,同时也是高效的处理手段。所以要想成为C/C+高手,对引用的概念没有透彻
9、的理解和熟练的应用是不行的。三数据指针在 C/C+语言中一直是很受宠的;几乎找不到一个不使用指针的C/C+应用。用于存储数据和程序的地址,这是指针的基本功能。用于指向整型数,用整数指针(int*);指向浮点数用浮点数指针(float*);指向结构,用对应的结构指针(struct xxx*);指向任意地址,用无类型指针(void*)。有时候,我们需要一些通用的指针。在C语言当中,(void*)可以代表一切;但是在C+中,我们还有一些比较特殊的指针,无法用(void*)来表示。事实上,在 C+中,想找到一个通用的指针,特别是通用的函数指针简直是一个“不可能任务”。C+是一种静态类型的语言,类型安全
10、在C+中举足轻重。在C语言中,你可以用void*来指向一切;但在C+中,void*并不能指向一切,就算能,也失去了类型安全的意义了。类型安全往往能帮我们找出程序中潜在的一些BUG。下面我们来探讨一下,C+中如何存储各种类型数据的指针。C+指针探讨(一)数据指针沐枫网志 1.数据指针数据指针分为两种:常规数据指针和成员数据指针 1.1 常规数据指针这个不用说明了,和C语言一样,定义、赋值是很简单明了的。常见的有:int*,double*等等。如:int value=123;int *pn=&value;1.2 成员数据指针有如下的结构:struct MyStruct int key;int va
11、lue;现在有一个结构对象:MyStruct me;MyStruct*pMe=&me;我们需要 value 成员的地址,我们可以:int *pValue=&me.value;/或int *pValue =&pMe-value;当然了,这个指针仍然是属于第一种范筹-常规数据指针。好了,我们现在需要一种指针,它指向MyStruct 中的任一数据成员,那么它应该是这样的子:int MyStruct:*pMV=&MyStruct:value;/或int MyStruct:*pMK=&MyStruct:key;这种指针的用途是用于取得结构成员在结构内的地址。我们可以通过该指针来访问成员数据:int va
12、lue=pMe-*pMV;/取得 pMe的 value 成员数据。int key=me.*pMK;/取得 me的 key 成员数据。那么,在什么场合下会使用到成员数据指针呢?确实,成员指针本来就不是一种很常用的指针。不过,在某些时候还是很有用处的。我们先来看看下面的一个函数:int sum(MyStruct*objs,int MyStruct:*pm,int count)int result=0;for(int i=0;i count;+i)result+=objsi.*pm;return result;这个函数的功能是什么,你能看明白吗?它的功能就是,给定count 个 MyStruct 结
13、构的指针,计算出给定成员数据的总和。有点拗口对吧?看看下面的程序,你也许就明白了:MyStruct me10=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 ;int sum_value=sum(me,&MyStruct:value,10);/计算 10个 MyStruct 结构的 value 成员的总和:sum_value 值 为 110 (2+4+6+8+20)int sum_key=sum(me,&MyStruct:key,10);/计算 10个 MyStruct 结构的 key 成员的总和:sum_key 值 为 100 (1+3+
14、5+7+19)也许,你觉得用常规指针也可以做到,而且更易懂。Ok,没问题:int sum(MyStruct*objs,int count)int result=0;for(int i=0;i QueryInterface(IID_SOMEINTERFACE,&p);此处,p 是 SOMEINTERFACE类型的指针,所以&p便是指针的指针,在QueryInterface返回的时候,如果调用成功,则变量 p 包含一个指向新的接口的指针。如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完全是一回事。如果你象下面这样声明函数:void func1(MYCLASS*&pMyClass);pMy
15、Class=new MYCLASS;,其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传p的地址&p,而是直接传 p 本身:MYCLASS*p=NULL;func1(p);在调用之后,p 指向一个新的对象。一般来讲,引用的原理或多或少就象一个指针,从语法上看它就是一个普通变量。所以只要你碰到*&,就应该想到*。也就是说这个函数修改或可能修改调用者的指针,而调用者象普通变量一样传递这个指针,不使用地址操作符&。至于说什么场合要使用这种方法,我会说,极少。MFC 在其集合类中用到了它-例如,CObList,它是一个CObjects 指针列表。class CObList:
16、public CObject ,/获取/修改指定位置的元素CObject*&GetAt(POSITION position);CObject*GetAt(POSITION position)const;这里有两个 GetAt函数,功能都是获取给定位置的元素。区别何在呢?区别在于一个让你修改列表中的对象,另一个则不行。所以如果你写成下面这样:CObject*pObj=mylist.GetAt(pos);则 pObj 是列表中某个对象的指针,如果接着改变pObj 的值:pObj=pSomeOtherObj;这并改变不了在位置pos 处的对象地址,而仅仅是改变了变量pObj。但是,如果你写成下面这样
17、:CObject*&rpObj=mylist.GetAt(pos);现在,rpObj 是引用一个列表中的对象的指针,所以当改变rpObj 时,也会改变列表中位置pos 处的对象地址-换句话说,替代了这个对象。这就是为什么CObList 会有两个 GetAt 函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不是对象本身。这两个函数都可以修改对象,但只有*&版本可以替代对象。在 C/C+中引用是很重要的,同时也是高效的处理手段。所以要想成为C/C+高手,对引用的概念没有透彻的理解和熟练的应用是不行的。五新手学习之浅析一下c/c+中的指针在学习 c/c+过程中,指针是一个比较让
18、人头痛的问题,稍微不注意将会是程序编译无法通过,甚至造成死机。在程序设计过程中,指针也往往是产生隐含bug 的原因。下面就来谈谈指针的应用以及需要注意的一些问题,里面也许就有你平时没有注意到的问题,希望能帮助各位读者理解好指针。一、我们先来回忆一下指针的概念吧,方便下面的介绍指针是存放地址值的变量或者常量。例如:int a=1;&a就表示指针常量(“&”表示取地址运算符,也即引用)。int*b,b表示的是指针变量(注意,是b表示指针变量而不是*b),*表示要说明的是指针变量。大家注意int*b2和 int(*b)2 是不同的,int*b 表示一个指针数组,而int(*b)2 表示含有两个元素的
19、int指针,这里要注意运算优先级问题,有助于理解指针问题。在这里大概介绍基本概念就够了,至于具体使用方法,如赋值等,很多书都有介绍,我就不多说了。二、应用以及注意的问题1、理解指针的关键所在对指针类型和指针所指向的类型的理解、指针类型:可以把指针名字去掉,剩下的就是这个指针例如:int*a;/指针类型为 int*int*a;/指针类型为int*int*(*a)8;/指针类型为 int*(*)8、指针所指向的类型:是指编译器将把那一片内存所看待成的类型。这里只要把指针声明语句中的指针名字和名字右边的“*”号去掉就可以了,剩下的就是指针所指向的类型。我之所以把他们放在第一位,是因为弄清楚他们是学c
20、/c+指针的重点,正确理解他们才能使你打好c/c+的编程基础。2、指针的应用传递参数。其实它可以相当于隐式的返回值,这就比return的方法更加灵活了,可以返回更多的值,看看下面的例子自然就明白了:#include iostream.h void example(int*a1,int&b1,int c1)*a1*=3;+b1;+c1;void main()int*a;int b,c;*a=6;b=7;c=10;example(a,b,c);cout*a=*a cout b=cout c=输出:*a=18 b=8 c=10 注意到没有,*a 和 b的值都改变了,而c 没有变。这是由于a1 是指向
21、*a(=6)的指针,也即与a是指向同一个地址,所以当 a1 指向的值改变了,*a 的值也就改变了。在函数中的参数使用了引用(int&b1),b1是 b的别名,也可以把它当作特殊的指针来理解,所以b的值会改变。函数中的参数int c1只是在函数中起作用,当函数结束时候便消失了,所以在main()中不起作用。3、关于全局变量和局部变量的一个问题先不废话了,先看看程序:#include“iostream.h”int a=5;int*example1(int b)a+=b;return&a;int*example2(int b)int c=5;b+=c;return&b;void main()int*
22、a1=example1(10);int*b1=example2(10);cout ”a1=”*a1 cout ”b1=”*b1a1;cin a2;cout ”a1=”cout ”a2=”a1;cin a2;cout ”a1=”cout ”a2=”delete(a1);注意,别忘了要释放内存空间delete(a2);到此就能输出正确的结果了。分配了适当的内存之后要注意释放内参空间,同时还应该注意不要超出所分配的内存的大小,否则会有溢出现象产生,导致不可预料的结果。5、关于特殊的指针引用引用有时候应用起来要比指针要灵活,用它做返回的时候是不产生任何变量的副本的这样减小了内存的占用,提高执行的速度。
23、引用使用起来要比指针好理解,比较直观。当引用作为参数时,不会改变参数的地址,因此可以作为左值。下面请看一个例子:#include“iostream.h”char ch5=”ABCD”;char&example(int b)return ch;void main()cout ”ch=”example(2)=”c”;cout”ch=”输出结果:ch=ABCD ch=ABcD 在实际编程过程中,可以灵活地引用或指针,尽量提高程序的可读性和执行效率。三、小结:指针是学习 c/c+的重点难点,主要原因是指针较为抽象,不容易理解。使用指针千万要明白让指针指向什么地方,如何让指针指向正确的地方。在深入系统底
24、层之中需要应用到大量的指针,因此需要理解好指针的基本概念,例如:指针类型和指针所指向的类型。平时应该对留心观察,了解程序的工作过程,必要时候可以对程序进行反汇编,加深对指针的理解,这种方法同样适合学别的编程方面的知识。四、结束:指针的应用是很广泛的,利用指针可以做很多事情,要成为一个好的程序员,必须对指针有比较深刻的了解。写本文的目的在于让大家对指针有更深一层的了解,提高指针的应用能力,内容大都是我在实际编程中遇到的问题。相信能给大家一定的帮助。六 C+中关于指针入门的最好的文章什么是指针?其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序
25、在内存的哪块区域可以找到数据。这是一个非常重要的概念,有很多程序和算法都是围绕指针而设计的,如链表。开始学习如何定义一个指针呢?就像你定义一个其它变量一样,只不过你要在指针名字前加上一个星号。我们来看一个例子:下面这个程序定义了两个指针,它们都是指向整型数据。int*pNumberOne;int*pNumberTwo;你注意到在两个变量名前的“p”前缀了吗?这是程序员通常在定义指针时的一个习惯,以提高便程序的阅读性,表示这是个指针。现在让我们来初始化这两个指针:pNumberOne=&some_number;pNumberTwo=&some_other_number;&号读作“什么的地址”,它
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 指针 学习 建议
限制150内