我们定义一个指针,比如char *pStr=NULL; pStr=myString(比如这里myString是一个字符串数组,它的内容为”HELLO”,首地址为0x123456)
这里需要说明几点:
1.&pStr实际上是表示该指针的地址,它占四个字节(32位OS),
2.PStr实际上是指针指向的字符串的首地址,这里可以认为是0x123456
3.*pStr实际上是表示字符串第一个字符的值,这里就相当于等于”H”。
考虑一个函数void SetContent(char *p)
这里传进来的实际上就是指针p指向的字符串的首地址,比如这样:
char *pStr=NULL;
SetContent(pStr);
//这里的pStr应该为什么呢?答案是还是NULL。
也就是说这个函数实际上修改的是指针p指向的字符串的内容。
如果指针p指向的字符串的内容是NULL,那么在函数SetContent中做的任何事情都没有什么意义。不会对调用该函数的过程产生任何影响。
函数SetContent的实现如下:
Void SetContent(char *p)
{
*p=’a’;
*p+1=’b’;
}
不管怎么说,因为这里根本没有对&pStr进行操作,所以&pStr中保存的内容永远都是0x123456。
但是因为p就是等于0x123456 ,所以可以通过修改p指向的内容来达到使pStr发生改变的目的,具体,比如:*p=’2’; *(p+3)=’H’等等如此。
但是如果在SetContent中采用如下的语句p=new char[100];它到底表示了什么意思呢?它表示我们一开始传给SetContent的是一个类型为char,地址为0x123456的指针,但是它现在要使该指针指向另外一个地址,也就是heap在执行new char[100]的时候返回的heap中的地址。那也没有,但是就是没什么意义。
这里需要注意的是,如果你要改变一个变量的值,那么必须得到它的地址,然后进行操作,比如如果你真正要改变&pStr的指向,你就需要对&pStr进行操作,也就是把指针的地址传给函数,可以采用如下的方法:
char *pStr=NULL;
SetContent_NEW(&pStr); //这里传给函数的就是指针的地址,可以改变指针的指向。
…..
delete []pStr;
看SetContent_NEW的实现:
void SetContent_NEW(char **p)
{
*p=new char[100]; //这里就改变了指针的指向
strcpy(*p,”askdfj….”);
}
所以比如我们定义了一个空的指针,然后我们需要在子函数中对该指针指向一个我们自己在heap中建立起来的一个对象的时候,就需要采用上面的方法,而实际上COM对象就是采用了类似的机制,比如:
IHTMLDocument *pHD;
lpDisp->QueryInterface(IID_IHTMLDocument,(LPVOID*)&pHD);
这里就是在QueryInterface这个函数中让pHD指向一个具体的对象。所以传递给QueryInterface的实际上就是指针的地址。