代码改变世界

指针和指针的引用浅谈

2010-12-23 11:43  Rollen Holt  阅读(295)  评论(0编辑  收藏  举报

这篇文章写的很杂,因为我查阅多方资料,呵呵,也没时间整理,所以大家就当是看意识流的吧。哈哈

首先来说说指针的引用如何赋予初值吧,我之前很简单的认为可以这样写,大家看下面的例子:

1
2 CFbsBitmap*& aBackgroudBitmap= NULL;
但是这样写是有问题的。我当时请教高手的时候人家说是c语言历史遗留下来的问题,
我也没搞清楚,那位大神要是明白的话麻烦说一下。
但是我知道,可以通过下面的形式赋予初值。
1 typedef int* A;
2 A oo;
3 A & ooo = oo;

我一般都是这样写的,哈哈,

接下来说说两者在释放内存方面的区别吧,看代码:

1 #include <iostream>
2 using namespace std;
3 void freePtr1(int* p1)
4 {
5 delete p1;
6 p1 = NULL;
7 }
8 void freePtr2(int*& p2)
9 {
10 delete p2;
11 p2 = NULL;
12 }
13
14 void main()
15 {
16 int *p1 = new int;
17 *p1 = 1;
18 freePtr1(p1);
19 int *p2 = new int;
20 *p2 = 2;
21 freePtr2(p2);
22 system("pause");
23 }
24 思考:在freePtr1和freePtr2 的比较中,你能发现它们的不同点吗?
25
26 二、对代码进行解释:
27 #include <iostream>
28 using namespace std;
29 void freePtr1(int* p1)
30 {
31 //未释放内存前 -> p1 Address : 0012FDDC p1 value : 003429B8,在这里,p1它也是一个变量,既然是一个变量,那么它将会以值的传递,把外部变量p1传到栈内,在栈内产生一个地址:0012FDDC,当然,它的值不会变仍然是指向堆地址:003429B8 。
32 delete p1; //系统回收p1值的地址003429B8处的内存。
33 p1 = NULL;//对p1赋以NULL值即:00000000,注意:p1本身的地址并没有变,变的是p1的值。
34 //释放内存后 -> p1 Address : 0012FDDC p1 value : 00000000,出栈后,p1由于是一个临时对象,出栈后它会自动被视为无效。
35 }
36 void freePtr2(int*& p2)
37 {
38 //未释放内存前 -> p2 Address : 0012FEC8 p2 value : 003429B8,p2是一个指针的引用,即引用指向指针,记住引用的特点:对引用的对象直接操作。所以它的地址和值与栈外的main()函数中,p2的值是同一个。
39 delete p2; //对p2所引用的指针进行释放内存,即:系统回收main()函数中 p2的值 003429B8 地址处的内存。
40 p2 = NULL;//对main()函数中p2的指针赋以NULL值。
41 //释放内存后 -> p2 Address : 0012FEC8 p2 value : 00000000,由于操作的对象都是main()函数中的p2,所以它将应用到原变量中。
42 }
43
44 void main()
45 {
46 int *p1 = new int;
47 //释放内存前-> p1 Address : 0012FED4 p1 value : 003429B8
48 freePtr1(p1);
49 //释放内存后-> p1 Address : 0012FED4 p1 value : 003429B8
50
51 int *p2 = new int;
52 //释放内存前-> p2 Address : 0012FEC8 p2 value : 003429B8
53 freePtr2(p2);
54 //释放内存后-> p2 Address : 0012FEC8 p2 value : 00000000
55 system("pause");
56 }
实际上你可以想象成 Int*&为 int **,所以内部当然可以修改他的值!但是**和*&,语义上是有区别的,但不少编译器却把两者等同对待,产生的代码是一样的(比如vc,可以disassemble瞧瞧),不过常常有先生指导咱后生在c++里能用&尽量不要用*,呵呵,遵照了便是

无论你传值还是传指针,函数都会生成一个临时变量,
但传递一个指针的引用时,不会生成临时变量~~~
传递指针和采用指针的引用,他们中间的具体实现过程是有所不同的。
参数传递指针时将直接对指针指向的地址进行操作
传递指针的引用时,通过间接寻址,来实现对[指针指向的地址]进行操作。
因为我们传指针,目的是在函数外面获得在函数里面改变的指针所指对象的值

 

而指针的引用,目的是在函数外面获得在函数里面改变的指针本身的值

 看个例子:

1 #include <iostream>
2 using namespace std;
3
4 void f1(int *&a)
5 {
6 int *b;
7 b=a;
8 }
9
10 void f2(int *a)
11 {
12 int *b;
13 b=a;
14 }
15
16 void main()
17 {
18 int m=10;
19 int *n=&m;
20
21 f1(n);
22 f2(n);
23
24 }
25 //---------------------------------------------------------------------------
26
27
28 * Referenced by a CALL at Address:
29 |:00401187
30 |
31 :00401150 55 push ebp
32 :00401151 8BEC mov ebp, esp
33 :00401153 51 push ecx
34 //[ebp+08]即为压栈内容:n的有效地址
35 :00401154 8B4508 mov eax, dword ptr [ebp+08]
36 //取得主函数中m的有效地址--》edx
37 :00401157 8B10 mov edx, dword ptr [eax]
38 //b=a;
39 :00401159 8955FC mov dword ptr [ebp-04], edx
40 :0040115C 59 pop ecx
41 :0040115D 5D pop ebp
42 :0040115E C3 ret
43
44
45 * Referenced by a CALL at Address:
46 |:00401190
47 |
48 :00401160 55 push ebp
49 :00401161 8BEC mov ebp, esp
50 :00401163 51 push ecx
51 //取得压栈内容:n的有效内容(即m的有效地址)
52 :00401164 8B4508 mov eax, dword ptr [ebp+08]
53 //b=a;
54 :00401167 8945FC mov dword ptr [ebp-04], eax
55 :0040116A 59 pop ecx
56 :0040116B 5D pop ebp
57 :0040116C C3 ret
58
59
60 ---------------> 函数开始 <----------------------------
61 :00401170 55 push ebp
62 :00401171 8BEC mov ebp, esp
63 :00401173 83C4F8 add esp, FFFFFFF8
64 int m=10;
65 :00401176 C745FC0A000000 mov [ebp-04], 0000000A
66 int *n=&m;
67 :0040117D 8D45FC lea eax, dword ptr [ebp-04]
68 :00401180 8945F8 mov dword ptr [ebp-08], eax
69 f1(n);
70 //由于形参是引用变量,所以将n的有效地址压栈
71 :00401183 8D55F8 lea edx, dword ptr [ebp-08]
72 :00401186 52 push edx
73 :00401187 E8C4FFFFFF call 00401150
74 :0040118C 59 pop ecx
75 f2(n);
76 //由于形参是指针变量,所以将n的有效内容压栈(即m的有效地址)
77 :0040118D FF75F8 push [ebp-08]
78 :00401190 E8CBFFFFFF call 00401160
79 :00401195 59 pop ecx
80 :00401196 59 pop ecx
81 :00401197 59 pop ecx
82 :00401198 5D pop ebp
83 :00401199 C3 ret
84
呵呵。大家还有什么高见多多留言啊,以上几处代码来自互联网,由于比较杂,本人整理的,所以不好写出处,忘原作者见谅啊、