您的位置:首页 > 编程语言 > C语言/C++

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

2013-04-06 10:41 477 查看
    (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)结论:在函数的参数中含指针,如果在函数中去对指针本身去操作,没有用的,传不回去。换句话说,只能对指针指向的内容去操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: