为什么使用双重指针

来源:互联网 发布:java模拟网页下载文件 编辑:程序博客网 时间:2024/06/10 05:00

一般情况下我们不使用指向指针的指针,因为这带来了操作的复杂性。但有些情况下我们不得不用。当指针作为一个函数的参数输出时,它的作用就显示出来了。

例如:设计一个函数:void fun1(char sz[], char search, char * pa)

要求:这个函数参数中的数组array是以0值为结束的字符串,要求在字符串sz中查找字符是参数search里的字符。如果找到,函数通过第三个参数(pa)返回值为sz字符串中第一个找到的字符的地址。如果没找到,则为pa为0。

实现代码如下:

void fun1(char sz[], char search, char* pa)

{

   for (int i=0;*(sz+i)!=0;i++)

   {

      if (*(sz+i)==search)

      {

        pa=sz+i;

        break;

      }

      else if (*(sz+i)==0)

      {

        pa=0;

        break;

      }

   }

}

 

int main(int argc, char* argv[])

{

    char str[]={"afsdfsdfdf/0"}; 

    char a='d';

    char *p=0; 

    fun1(str,a,p);

    if (0==p)

    {

       printf("没找到!/n");

    }

    else

    {

       printf("找到了,p=%d",p); 

    }

    return 0;

}

令人奇怪的是:输出的结果为—-没找到。为什么没找到呢?

问题出在:参数传递时。

函数调用时会对每一个参数进行一个隐含的赋值操作。

如:sz = str;

    Search = a;

    Pa = p; //以上三句是调用时隐含的动作。

    ……

参数pa与参数search的传递并没有什么不同,都是值传递。所以对形参变量pa值(当然值是一个地址值)的修改并不会改变实参变量p值,因此p的值并没有改变(即p的指向并没有被改变)。

 

修改后:

void fun2(char sz[], char search, char** ppa)

{

   for (int i=0;*(sz+i)!=0;i++)

   {

      if (*(sz+i)==search)

      {

        *ppa=sz+i;

        break;

      }

      else if (*(sz+i)==0)

      {

        *ppa=0;

        break;

      }

   }

}

int main(int argc, char* argv[])

{

    char str[]={"afsdfsdfdf/0"}; 

    char a='d';

    char *p=0; 

    fun2(str,a,&p);

    if (0==p )

    {

       printf("没找到!/n");

    }

    else

    {

       printf("找到了,p=%d",p); 

    }

    return 0;

}

这时调用函数时的操作变成如下:

sz=str;

   search=a;

   ppa=&p;    //以上三句是调用时隐含的动作。

   ……

ppa指向指针p的地址。

对*ppa的修改就是对p值的修改。

 

再举个例子:

void GetMemory(char* p)

{

    p = "bbb";

}

int main(int argc, char* argv[])

{

    char *v = "aaa";

    GetMemory(v);

    cout<< v <<endl;

    return 0;

}

我们发现输出的结果仍然是aaa。

 

对它进行修改:

void GetMemory(char** p)

{

    *p = "bbb";

}

 

int main(int argc, char* argv[])

{

    char *v = "aaa";

    GetMemory(&v);

    cout<< v <<endl;

    return 0;

}

此时输出的结果为bbb.

操作过程中,指针v本身的地址值始终没有改变,改变的是指针v所指向的地址变化了。它不再指向”aaa”所在的地址,而是”bbb”所在的地址。

 

所以我们经常会在COM里面看到双重指针的使用。比如QueryInterface来获取指针,指针ppv通过函数的一个参数的形式向外输出。就是这个原因。

STDMETHODIMP QueryInterface(REFIID riid, void **ppv)

 {

      if( riid == IID_IBird || riid == IID_IUnknown )

          *ppv = static_cast<IBird*>(this);

      else if( riid == IID_ISnappyDresser )

          *ppv = static_cast<ISnappyDresser*>(this);

      else *ppv = 0;

 

      if( *ppv ) {

          reinterpret_cast<IUnknown*>(*ppv)->AddRef();

          return S_OK;

      }

 

      return E_NOINTERFACE;

  }

 


CopyFrom: http://blog.csdn.net/zp_wan/article/details/2775777

原创粉丝点击