指针和引用的区别(指针和引用的区别有 非空区别 可修改却区别)
大家好,今天就和毛毛一起来看看这个问题吧 。指针和引用的区别有 非空区别 可修改却区别,指针和引用的区别很多人还不知道,现在让我们一起来看看吧!
1、 举个最简单的例子。
2、 void tmp(int* b)
3、 {
4、 if (b==NULL)
5、 {
6、 b=new int
7、 * b=200
8、 }
9、 其他
10、 {
11、 * b=100
12、 }
13、 }
14、 void main()
15、 {
16、 int a=0;
17、 tmp(a);
18、 int * c=NULL
19、 //c=new int;
20、 tmp(c);
21、 返回;
22、 }
23、 在main中调用tmp函数有两种方法。第一种方式是通过引用。因为引用不能为空,所以是直接定义一个int,然后用引用的方法传递地址。
24、 第二种方式是指针。如果指针C在调用tmp之前指向空的和未分配的空间,那么空间将在tmp中被分配,然后被赋值。但是,tmp被调用后,C将不是tmp中赋值的值。
25、 好吧,那我们明白了。当指针被传递时,它实际上复制了指针的地址。请注意,这是副本。如果在被调用的函数中修改内存指向的值,那么函数调用结束,你返回到调用函数,修改有效,即修改成功。这相当于在被调用的函数中声明了一个int*变量,它的值就是传递的int*。
26、 int * b=int * c;
27、 那么在被调用函数的栈中修改自己定义的int*b当然不会影响int * c的地址.
28、 一般来说,引用实际上是一个地址,C语言中取地址符号是
29、 然后,如果你想在被调用的函数中申请空间,那么就使用引用。如果在调用前申请空间,只需要修改被调用函数中指向的值,那么引用和指针都是可以的。
30、 因此,建议引用。
31、 c指针使用方法解决困惑
32、 在下面的函数声明中,为什么同时使用*和符号?以及这个宣言会在什么场合使用?
33、 void func 1(my class * pBuildingElement);论坛上经常有人问这样的问题。本文试图通过一些使用指针的实践经验来解释这个问题。
34、 仔细看这个说法有点混乱。从某种意义上来说,“*”和“”是两个意思相反的东西。把它们放在一起有什么意义?为了理解指针的这种做法,我们先来回顾一下C/C编程中无处不在的指针概念。我们都知道MYCLASS*的意思:指向类型为MYCLASS的对象的指针。
35、 void func 1(my class * pmy class);
36、 //例如:
37、 MYCLASS* p=新的my class;
38、 func 1(p);上面代码的这种处理方式想必大家都用过。创建一个MYCLASS对象,然后将其传递给func1函数。现在假设这个函数想要修改pMyClass:
39、 void func1(MYCLASS *pMyClass)
40、 {
41、 do something(pmy class);
42、 PMyClass=//指向其他对象的指针
43、 }
44、 第二条语句只修改function过程中pMyClass的值。调用者的变量p的值不被修改。如果p指向地址为0x008a00的对象,当func1返回时,它仍然指向这个特定的对象。(除非func1有bug会搞乱堆,这是完全有可能的。)
45、 现在假设你想修改func1中p的值。这是你的权利。调用者传入一个指针,然后函数给这个指针赋值。以前它用来传递双指针,也就是指针的指针,比如CMyClass**。
46、 MYCLASS * p=NULL
47、 func 1(p);
48、 void func 1(my class * * pmy class);
49、 {
50、 * pMyClass=new MYCLASS
51、 ……
52、 }
53、 调用func1后,p指向新对象。在COM编程中,到处都会遇到这样的用法——例如,在查询对象接口的QueryInterface函数中:
54、 接口等距接口{
55、 HRESULT QueryInterface(IID iid,void * * ppvObj);
56、 ……
57、 };
58、 LPSOMEINTERFACE p=NULL
59、 po b-query interface(IID _ some interface,p);
60、 这里p是SOMEINTERFACE类型的指针,所以p是指针的指针。当QueryInterface返回时,如果调用成功,变量p包含一个指向新接口的指针。
61、 如果你理解指针的指针,那么你就必须理解指针引用,因为它们完全是一回事。如果您像这样声明一个函数:
62、 void func 1(my class * pmy class);
63、 {
64、 pMyClass=new MYCLASS
65、 ……
66、 }
67、 其实和前面说的指针的指针例子是一样的,只是语法不同。转的时候不需要转P的地址P,直接转P本身:
68、 MYCLASS * p=NULL
69、 func 1(p);
70、 调用后,p指向一个新对象。总的来说,指称原则或多或少有点像指针,是语法中常见的变量。所以每当遇到*,就要想到* *。也就是说,这个函数修改或者可能修改调用者的指针,调用者像传递普通变量一样传递这个指针,而不使用地址操作符。
71、 至于什么场合使用这种方法,我会说,很少。MFC在其集合类中使用它——例如,CObList,它是CObjects指针的列表。
72、 类CObList:公共CObject {
73、 ……
74、 //获取/修改指定位置的元素
75、 CObject* GetAt(位置POSITION);
76、 CObject * GetAt(POSITION POSITION)const;
77、 };
78、 这里有两个GetAt函数,都用来获取给定位置的元素。有什么区别?
79、 区别在于,一个允许您修改列表中的对象,而另一个不允许。所以如果你这样写:
80、 CObject* pObj=mylist。GetAt(位置);
81、 那么pObj就是指向列表中某个对象的指针。如果pObj的值随后改变:
82、 pObj=pSomeOtherObj
83、 这不会改变位置pos处对象的地址,而只会改变变量pObj。然而,如果你这样写:
84、 CObject* rpObj=mylist。GetAt(位置);
85、 现在,rpObj是一个指向列表中一个对象的指针,所以当你改变rpObj时,你也将改变列表中位置pos处的对象的地址——换句话说,替换这个对象。这就是为什么CObList有两个GetAt函数。一个可以修改指针的值,另一个不能。注意,我这里说的是指针,不是对象本身。这两个函数都可以修改对象,但是只有*版本可以替换对象。
86、 在C/C中引用非常重要,也是一种高效的处理方法。所以,想要成为C/C高手,没有对引用概念的透彻理解和熟练运用是不行的。
这篇文章到此就结束,希望能帮助到大家。
扫描二维码推送至手机访问。
版权声明:文章内容摘自网络,如果无意之中侵犯了您的版权,请联系本站,本站将在3个工作日内删除。谢谢!