c语言中,为什么 被调函数的形参 有时用二级指针(指针的指针),有时用一级指针
首先,要明白c语言是值传递,其次,要明白指针是保存地址的变量
一、如果 主调函数的指针p 已经有确定的指向且不需要在被调函数中改变它的指向(确定的指向也就是它的值,当然这个值一定是一个具体的地址,而不是NULL或野指针),只需要对指针p指向的地址进行操作,那么,被调函数形参 用一级指针就可以了;
二、假如 主调函数的指针p 没有具体指向(NULL,也可能是个野指针)或有具体指向,需要在被调函数中改变p的指向(给它赋予一个新的值,当然这个值是一个地址了),那么被调函数的形参pp就需要用二级指针(即指针的指针,主调函数传递的是指针p的地址的值,即&p),在被调函数中对指针的指针pp进行解引用(*pp):即通过保存在pp变量里的值(即p的地址),找到主调函数指针p,在被调函数中,向(*pp)(也就是p)写值,就可以改变p的指向了,比如在被调函数中malloc一个空间,将该空间的地址赋值给p。
注:可以改变形参一级指针的指向(指针变量的值),但对实参一级指针毫无影响(实参指针变量的值没有改变)
结构体包装一级指针,传结构体一级指针,实现结构体包装里的一级指针的指向改变(上面理解后再看)
#include <stdio.h> #include <stdlib.h> //malloc typedef struct node NODE; struct node{ int *p; }; void func( NODE *pNode){ //主调函数pNode的值,传递给被调函数pNode //主调函数的pNode的指向即是被调函数pNode的指向 //pNode指向的空间是NODE结点 pNode->p = (int*)malloc( sizeof(int) ); //对pNode指向的空间进行操作: 给NODE结点的成员p赋值,p有了具体指向 *( pNode->p ) = 100; } int main() { //创建NODE结点(动态分配空间) NODE *pNode = (NODE* )malloc( sizeof(NODE) ); // 一级指针pNode func(pNode ); printf("%d\n", *( pNode->p ) ); free(pNode->p ); //释放调用函数分配的空间 free(pNode ); //释放结点空间 return 0; }