关于C/C++中指针做形参的一点小分析(转)

 

2009-07-26 15:50

今天寝室的山东兄弟在练二级的上机,其中一个题目大概是这样:在一个函数中,有一个指针形参,记为*p,然后在函数内部定义了临时变量a,a和*p是同种类型。经过一系列计算 ,a得到了一个值,这个值最后是需要记录在指针*p里面的,应该怎么保存呢?我当时随便就说,p=&a。结果发生错误了,没有得到预期结果。正确答案是*p=a。

下面来分析下原因。

学过C的人都知道到,函数的实参与形参的之间是值传递,单向传递。在谭浩强那本C语言教材中就有这样一个经典的例子:

int a=3,b=4 ;

void exchange(int x,int
y)

...
{  

          
int
temp;

           temp
=a;a=b;b=temp;   //试图交换a,b


}


exchange(a,b);

cout
<<a<<" "<<b<< endl;

输出的来的仍然是3,4.

要交换a,b,只需改变函数exchange,传递a,b的地址,如下:

void exchange(int *x,int * y)

{

         
int
temp;
          temp
=*x;*x=*y;*y=
temp;
}
   exchange(&a,&b);
   cout<<a<<" "<<b<<endl;
  

这样,a,b就成功交换了。为什么呢?下面再说。

再回到开始提出的那个问题,为什么p=&a错误而*p=a正确呢?

再看两段代码:

#include<iostream>
using namespace std;
void test_point(int *
p)
...
{
     
int a=3
;
      p
=&
a;   // 不同之处
}

int main()
...
{
     
int x=4
;
     
int *p1=&
x;
      test_point(p1);
      cout
<<*p1<<endl;
         return 0;
}

   
   

此时输出的结果是4,也就是说,指针p1调用test_point函数后值并没有得到改变,接着看下一段代码

#include<iostream>
using namespace std;
void test_point(int *
p)
...
{
     
int a=3
;
     
*p=
a;   //不同之处
}

int main()
...
{
     
int x=4
;
     
int *p1=&
x;
      test_point(p1);
      cout
<<*p1<<
endl;
     
return 0
;
}

此时输出结果是3,证明指针p1在调用test_point函数后得到改变。

不难发现,两段代码不同之处在于函数中对p的处理,一个是p=&a,一个是*p=a,有什么区别呢?

翻开C++ primer(第四版)105页可以发现其中的解释:

对p=&a,称之为给指针赋值,意思是给指针本身一个指向的对象。

而对*p=a称之为通过指针进行赋值,意思是改变指针所指对象的值。

有了上面的基础就很好解释了,p=&a是相当于把函数的形参指针p指向a(即给指针赋值,此值是a的地址),但由于a是临时变量,函数调用完后即不存在了,所以实参p1是不会被改变的,*p1=4。

而*p=a就不同了,我们知道,函数是值传递,实参p1传递给形参p的值是什么呢?当然是x的地址,也就是说,在函数test_point调用的过程中,形参指针p指向了x,然后进行的*p=a是通过指针进行赋值,改变了p指向的对象x,p1仍然指向x,故*p1=3.

 

这样,那个exhange函数也很好解释了,也就是一个通过指针进行赋值的问题。

你可能感兴趣的:(c,语言,Exchange)