理解二级指针
来源:互联网 发布:android wifi定位源码 编辑:程序博客网 时间:2024/05/18 22:16
举两个小例子来看看吧。
1。用二级指针动态申请二维数组:
int main(){ int m , n , **p; scanf("%d%d" , &m , &n); p = (int **)malloc(m * sizeof(int *)) //C++中建议使用:p = new int* [m]; for(i = 0 ; i < m ; i++) p[i] = (int *)malloc(n * sizeof(int)); //C++:p[i] = new int[n];}
这样就实现了二维数组的动态申请,因为一般数组声明时,不允许下标是变量,所以如果想动态决定数组各维的大小,最好这样做。
2。使用二级指针传递参数,可以在函数内部修改一级指针。
或许,你已经很熟悉通过传递一级指针,可以在函数内部修改实参指针指向的内容:如:
void f(char *p){ p[2] = 'a';//由实参指向的函数外部的数组的内容就被改变了。 ……}
但是,如果我们想改变实参本身呢?也就是说,我们连指针值都要改变,如果使用:
void f(char *p){ p = (char *)malloc(10 * sizeof(char)) //或C++中:p = new char[10]; ……}
就不行了,因为在函数内部不能通过改变形参的值来改变实参(注意这里实形参是指针p,上面的那个函数并没有改变形参,只是改变了形参指向的内容,只是由于形参和实参的值相同,也就是指向同一块内存,所以也就是改变了实参指向的内容,这个时候就要用二级指针了)。
void f(char **p){ *p = new char[10]; *p[2] = 'a'; ……}
可以这样说,传入一个N级指针,就可以修改N-1级指针,原因就是C的参数传递是值传递的,直接修改形参根本改变不了实参,但可以改变行参指针指向的内容,而N级指针指向的内容就是一个N-1级指针(你可以把非指针变量理解为0级指针),另外,你可能感觉这样使用似乎有问题,因为原先的内存空间没有释放,是的,这只是个为了说明问题的简化了的例子,实际的应用场合要比这合适的多。
最后,指针是C/C++语言的精华,但理解指针还是应该从指针本身去理解,二级指针只是指针的一种,不应该在这里钻牛角尖,多级指针其实还是指针,只不过它指向的内容内容仍是指针而已。
接下来通过二叉查找树的插入算法来分析:
算法大体的C语言描述:
Status SearchBST1(BiTree *T,KeyType key,BiTree f,BiTree *p) { /* 在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找 */ /* 成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上 */ /* 访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL */ if(!*T) /* 查找不成功 *///① { *p=f; return FALSE; } else if EQ(key,(*T)->data.key) /* 查找成功 */ { *p=*T; return TRUE; } else if LT(key,(*T)->data.key) return SearchBST1(&(*T)->lchild,key,*T,p); /* 在左子树中继续查找 */ else return SearchBST1(&(*T)->rchild,key,*T,p); /* 在右子树中继续查找 */ }
Status InsertBST(BiTree *T, ElemType e) { /* 当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE,否则返回FALSE。 */ BiTree p,s; if(!SearchBST1(T,e.key,NULL,&p)) /* 查找不成功 *///② { s=(BiTree)malloc(sizeof(BiTNode)); s->data=e; s->lchild=s->rchild=NULL; if(!p) *T=s; /* 被插结点*s为新的根结点 *///③ else if LT(e.key,p->data.key) p->lchild=s; /* 被插结点*s为左孩子 */ else p->rchild=s; /* 被插结点*s为右孩子 */ return TRUE; } else return FALSE; /* 树中已有关键字相同的结点,不再插入 */ }
对算法中二级指针的理解:
- 在这个函数中T也使用了二级指针,但是我认为这里二级指针没有什么用武之地,一级足够了吧。因为这里的T仅仅起到指示递归过程中的根节点的作用,而且T的改变对主调函数来说是没有意义的。
- 在这里传递给递归函数SearchBST1的是指针p的地址,在这里使用了二级指针。因为我们需要通过p来实现:若查找成功指向查找到的节点,若查找失败指向查找路径上最后一个节点,所以这其中p必然会不断移动,而且p是通过传参在其他函数中实现的移动。所以如果仅仅传递p,SearchBST1得到的仅仅是一份拷贝,它是通过一个在栈中新定义的一个指针变量来实现的移动,而且在SearchBST1函数结束后新定义的变量会收回(当然,因为二叉查找树的结构是存储在堆中的,最后可以通过返回局部变量的指针来实现对p的定位,这样就不需要二级指针了。但是因为要通过一个布尔值来判断查找的结果,所以还是不要用这种方法比较好),就无法实现下面通过p进行的插入操作了。
- 这里的T也是个二级指针,它的使用方法跟一开始讲的第2个小例子差不多。一般调用InsertBST的函数会定义一个变量BiTree T,然后通过InsertBST(&T,e)进行调用。因为要使T指向在被调函数中分配给它的内存的地址,所以最好使用二级指针。
0 0
- 理解二级指针
- 二级指针的理解
- 理解二级指针
- 二级指针的理解
- 关于二级指针的理解
- C++ 二级指针的理解
- 深入理解指针以及二级指针(指针的指针)
- C/C++中二级指针的理解
- C/C++中二级指针的理解
- C/C++中二级指针的理解
- 今天对二级指针的深入理解
- 二级指针理解 + static的特殊用法
- 二级指针
- 二级指针
- 二级指针
- 二级指针
- 二级指针
- 二级指针
- 大数据 阶乘
- IT求职整理Ⅱ----数据库范式1NF 2NF 3NF BCNF(实例)
- configure ,make ,make install
- svm系列四
- QMAKESPEC,生成不同平台的makefile
- 理解二级指针
- windows下TortoiseSVN 文件冲突解决详细步骤 (图)
- GoF的23个经典设计模式
- 把二叉树转化成双向连表
- svm系列五
- 深入C++的new
- svm系列六
- bShare分享插件的使用
- 网站安全-java实现小型网站登录破解攻略