Chinaunix首页 | 论坛 | 博客
  • 博客访问: 554396
  • 博文数量: 92
  • 博客积分: 2511
  • 博客等级: 少校
  • 技术积分: 932
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-19 10:10
文章分类
文章存档

2011年(6)

2010年(27)

2009年(37)

2008年(22)

我的朋友

分类: C/C++

2008-12-25 10:36:04

应该有不少人有这样的概念,就是指针能改变值,但是,不是说函数的参数是一个指针的时候,对形参的改变就一定会作用到实参上,这里产生误区的原因就是对传值和传引用的理解。在CSDN上的一个帖子加深了我的理解,先看一段代码

#include<iostream>
using namespace std;
void f(int*);
void g(int*);
void h(int*&);
void main()
{
    int i = 21;
    int *pp = &i;
    cout<<*pp<<endl;
    f(pp);
    cout<<*pp<<endl;
    g(pp);
    cout<<*pp<<endl;
    h(pp);
    cout<<*pp<<endl;
}

void f(int *p)
{
    int* ppp = new int(9);
    p = ppp;
    delete ppp;//不产生野指针

}

void g(int* p)
{
    int* ppp = new int(56);
    *p = *ppp;
    delete ppp;//不产生野指针

}

void h(int* &p)
{
    int* ppp = new int(43);
    p = ppp;
    delete ppp;//产生野指针


}

 


在VC++6.0 + WIN运行结果:

21

56

-572662307

Press any key to continue

现在我来一一解释为什么会这样。

f()中,我们传入了一个指针,但是这个指针是以传值的形式作用的,也就是说函数里产生了一个local指针作为这个实参的副本(注意与下文的别名区分),所有作用在这个local指针上的行为都不影响实参。所以我们任然得到了*pp = 21

第二个是g()肯定会有人立刻用我以上的解释来对我现在要说的做矛盾之击,这里确实有迷惑的地方,仔细看两者的区别,在f()中我们用的是

p = ppp;而在g()中我写的是

*p = *ppp;

我们可以试想这样的一张图,对于f()

pp------------->&i<--------------p,做了p = ppp

pp------------->&i

p-------------->ppp;

delete ppp

pp------------>&i//因为p只不过是pp的一个副本

p------->ppp----->unknow

而对于在g()中呢,就不一样了

pp----------->&i<-----------p

做了*p = *ppp我们从图上发现p依旧是指向&i//因为我们没有对p重新赋值

delete ppp

pp---------->&i<------------p//当然,函数结束后p销毁

ppp--------->unknow

再来看看h(),我相信就比较容易理解了,这里的ppp的一个别名(注意!不是副本)所以所有的改变都会对实参产生影响,在我们delete ppp后,pp也自然而然的成为了一个野指针。

 

阅读(3707) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~