二级指针:为什么用(Bitree *T)而不用(Bitree T)?

struct TreeNode
{
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};
typedef struct TreeNode TNode;
typedef struct TreeNode *Bitree;

看到很多关于树的题目中,我总是看到在传参的时候使用的是(Bitree *T).

我的疑惑是:如果要把树的指针传过去,那直接(Bitree T)就可以了啊。Bitree已经是指针类型了。

参考https://bbs.csdn.net/topics/60261634

Bitree *T的含义是T是一个二级指针。

T_Pointer Build_Tree(T_Pointer T)
{
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
    {
       T=NULL;
    }
    return T;
}

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第1张图片

T_Pointer Build_Tree(T_Pointer *T)
{
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
    {
       T=NULL;
    }
    return T;
}

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第2张图片

调试的时候我又迷惑了,两段代码中,从主函数传过去的指针到了Build_Tree()中仍然是一样的。

于是我去翻了一篇二级指针的博客。这才明白了。

参考https://www.cnblogs.com/reality-soul/p/6372915.html

#include 
#include 

void change(int x_temp)
{
    x_temp=1;
}
int main()
{
    int x=0;
    change(x);
    printf("%d",x);
    return 0;
}

运行结果:
二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第3张图片
C语言中函数传递参数都是传递"值"的。因为我们传递的是“值”,如果你想在函数change()中修改这个x的值能在main()中生效的话,那么就需要用指针来传递了。

#include 
#include 

void change(int *p_temp)
{
    *p_temp=1;
}
int main()
{
    int x=0;
    int *p=&x;
    change(p);
    printf("%d",x);
    return 0;
}

运行结果:
二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第4张图片
在这里复习一下p,*p,&:

*p表示此指针指向的内存地址中存放的内容。

p表示一个指针变量的名字,指此指针变量所指向的内存地址。

&在c中是取地址,在C++中是引用。

到这里的时候我们可以试想一下,我们通过传递指针来达到修改一个值的目的,那么当你需要修改一个指针的时候呢,这个时候我们就需要指针的指针了。

#include 
#include 

struct TreeNode
{
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};
typedef struct TreeNode TNode;
typedef struct TreeNode *T_Pointer;

void Build_Tree(T_Pointer *T)
{
    *T=NULL;
}
int main()
{
    T_Pointer root;
    root=(T_Pointer)malloc(sizeof(TNode));
    Build_Tree(&root);//注意此时要加“&”,传递的是指针root的地址。
    if(root==NULL)
    {
        printf("NULL");
    }
    else
    {
        printf("Not NULL");
    }
    return 0;
}

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第5张图片
注意不能是T=NULL。搞清楚T是二级指针。*T的值才是root的值。

调试的过程中我还发现一个问题。如果Build_Tree()里是T=NULL;调试的时候我发现T的值并没有发生改变。

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第6张图片
T的值不等于NULL啊,这是怎么回事。

后来我在修改的过程中无意添加了一条语句:T_Pointer **p=&T;

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第7张图片
执行完之后,T的值就等于NULL了。我的猜测是,在没有三级指针p存储二级指针T的地址的时候,改变不了T的值?

让我们再返回到最简单的函数传参:

#include 
#include 

void change(int x_temp)
{
    x_temp=1;
    printf("%d的地址为:%p\n",x_temp,&x_temp);
}
int main()
{
    int x=0;
    change(x);
    printf("%d的地址为:%p\n",x,&x);
    return 0;
}

运行结果:
二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第8张图片
虽然把x传过去了,但是x_temp的地址和x的地址是不一样的。

也就是说,如果是void Build_Tree(T_Pointer T)+主函数的Build_Tree(root)。传过去之后,root的值和T的值是不一样的 。root的值和T的值是一样的,但是它们的地址值是不一样的。

二级指针:为什么用(Bitree *T)而不用(Bitree T)?_第9张图片
如果要在另一个函数里修改一个指针的值:

那么就要使用多一级指针,如果是2重指针,就要使用3重指针,同时在这个函数里面,分配指针的时候一定要以一个指针带指针名为单位进行地址的分配。

参考:https://blog.csdn.net/ztz0223/article/details/2026890

写得乱七八糟的。先这样吧。

————————我是分割线———————————

在C++中,可以不用二级指针传递T。可以用引用&。

Build_Tree(root);//不同于c的Build_Tree(&root)
void Build_Tree(T_Pointer &T)//不同于c的(T_Pointer *T)
{
    T=NULL;
}

而且在调试的过程中我发现,C++中一级指针不能赋值给二级指针,在C中一级指针可以赋值给二级指针。(似乎是这样吧。)

error: cannot convert 'T_Pointer {aka TreeNode*}' to 'TreeNode**' for argument '1' to 'void Build_Tree(TreeNode**)'

你可能感兴趣的:(技巧)