一般情况下我们不使用指向指针的指针,因为这带来了操作的复杂性。但有些情况下我们不得不用。当指针作为一个函数的参数输出时,它的作用就显示出来了。
例如:设计一个函数: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