本文仅作为关于指向指针的指针与指针引用相关的内容的总结,如有不对的地方,欢迎交流。
如果想改变指针本身而不是它所指向的对象(i),一般有以下两种函数声明的方式:
1 #include <iostream> 2 3 using namespace std; 4 5 void f(int** j) { *j++; } 6 void g(int*& j) { j++; } 7 8 int main() 9 { 10 int i = 0; 11 int* p = &i; 12 13 int size = sizeof(int); 14 cout << "sizeof int:" << size << endl << endl; 15 16 cout << "f(int** j): " << endl; 17 cout << "p " << p << endl; 18 cout << "i " << i <<endl; 19 f(&p); 20 cout << "p " << p << endl; 21 cout << "i " << i <<endl; 22 23 i = 0; 24 p = &i; 25 26 cout << "g(int*& j): " << endl; 27 cout << "p " << p << endl; 28 cout << "i " << i << endl; 29 g(p); 30 cout << "p " << p << endl; 31 cout << "i " << i << endl; 32 33 system("pause"); 34 return 0; 35 }
运行结果如下:
我们看到,调用g(int*& j),p的输出正常,而调用f(int** j)的运行结果却不符合预期,正常情况下p应该为下一个4字节的地址,这是为什么?
问题出在函数定义中,void f(int** j) { *j++; }中++的运算优先级高于*,所以并没有出现预期的结果,将定义改为:void f(int** j) { (*j)++; }
再次运行代码:
这次结果符合了预期。
分析:当函数的形参为指针时,在函数内部会复制实参指针,因而形参(ip)在函数内部的任何改变都无法影响实参。然而,传入的指针形参却可以改变指针指向的对象(*ip)的值。
1 void reset(int* ip) 2 { 3 ip = 0; //形参在函数内部的改变无法影响实参 4 *ip = 0; //改变了ip所指向对象的值 5 }
当函数的形参为指向指针的指针,如本例void f(int** j) { (*j)++; }中,是如何改变j指向的对象呢?其中j,*j,i之间的指向关系如下
参数j是一个指向指针的指针,说白了就是*j的地址,j指向的对象就是*j(对象i的地址)。将j传入函数内部,产生j的拷贝j',改变j‘指向的对象的值,就改变了*j,从而达到目的,看到指针本身*j的内容增加了,而不是它指向的对象(i)增加了。