C++一些注意点之函数参数为指针

    (1)平时比较常用的swap函数代码

#include <iostream>

using namespace std;

void swap(int *a,int * b)
{
    int c = *a;
    *a = *b;
    *b = c;
}

int main(void)
{
    int d1 = 2;
    int d2 = 3;
    swap(&d1,&d2);
    cout<<d1<<"  "<<d2<<endl;
    system("pause");
    return 0;
}

上面这段代码是没有问题的,首先a复制了d1的地址,b复制了d2的地址。虽然函数调用结束后,局部变量a和b都被释放了,但是由于在函数里面的操作都是对指针里面的内容进行操作,所以函数的改变保存下来了。

    (2)同样,下面代码也是没有问题的,因为,其实在函数setChild(Btree *p)函数中的操作;

                                       p->pLeft = new Btree(2);

                                       p->pRight = new Btree(3);

还是对指针所指向的内容进行操作,这样的操作不会出现问题。虽然函数结束后,p指针被释放。

#include <iostream>

using namespace std;

struct Btree{
	Btree *pLeft,*pRight;
	int mValue;
	Btree(int v = 0):mValue(v),pRight(NULL),pLeft(NULL){};
};

void setChild(Btree *p)
{
	p->pLeft = new Btree(2);
	p->pRight = new Btree(3);
}

int main(void)
{
	Btree *bt = new Btree;
	setChild(bt);
	cout<<bt->pLeft->mValue<<" "<<bt->pRight->mValue<<endl;
	system("pause");
	return 0;
}

    (3)下面这段代码就有问题了。预测结果,将会输出0,因为这样其实并没有改变bt指针改变的内容。

#include <iostream>

using namespace std;

struct Btree{
	Btree *pLeft,*pRight;
	int mValue;
	Btree(int v = 0):mValue(v),pRight(NULL),pLeft(NULL){};
};

void setP(Btree *p)
{
	p = new Btree(3);
}

int main(void)
{
	Btree *bt = new Btree;
	setP(bt);
	cout<<bt->mValue<<endl;
	system("pause");
	return 0;
}

要实现上面的功能,void setP(Btree *p) 的参数改成指针引用进行传递或者指向指针的指针进行传递。具体代码如下:

#include <iostream>

using namespace std;

struct Btree{
	Btree *pLeft,*pRight;
	int mValue;
	Btree(int v = 0):mValue(v),pRight(NULL),pLeft(NULL){};
};

void setChild(Btree *&p)
{
	p = new Btree(3);
}

int main(void)
{
	Btree *bt = new Btree;
	setChild(bt);
	cout<<bt->mValue<<endl;
	system("pause");
	return 0;
}

或者代码可以这样

#include <iostream>

using namespace std;

struct Btree{
	Btree *pLeft,*pRight;
	int mValue;
	Btree(int v = 0):mValue(v),pRight(NULL),pLeft(NULL){};
};

void setChild(Btree **p)
{
	*p = new Btree(3);
}

int main(void)
{
	Btree *bt = new Btree;
	setChild(&bt);
	cout<<bt->mValue<<endl;
	system("pause");
	return 0;
}

(4)经常出现在人家博客上的一个例子

        如果函数的参数是一个指针,不要指望用该指针去申请动态内存。示例7-4-1中,Test 函数的语句  

GetMemory(str, 200)并没有使str获得期望的内存,str依旧是NULL,为什么?

void GetMemory(char *p, int num)
{
    p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
   char *str = NULL;
   GetMemory(str, 100); // str 仍然为 NULL
   strcpy(str, "hello"); // 运行错误
} 


     毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副 本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因 为没有用free释放内存。


(5)结论:在函数的参数中含指针,如果在函数中去对指针本身去操作,没有用的,传不回去。换句话说,只能对指针指向的内容去操作。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值