为什么我们在使用函数时需要返回指针?

时间:2021-01-15 21:04:12

标签: c function tree return binary-search-tree

我正在尝试编写代码以使用函数 insert_elements 在二叉搜索树中插入节点。 在我的教科书中,函数的代码是-

struct node *root;
int main(){
    root = insert_elements(root, val); // val is the value to be inserted
    return 0;
}
struct node *insert_elements(struct node *root, int val){
    // code to insert node
    return root;
}

我不明白为什么我们在函数insert_elements中返回根指针,为什么我们不将函数返回值更改为void并且什么都不返回! 将不胜感激任何帮助之王。

3 个答案:

答案 0 :(得分:3)

通常你会这样做,因为插入操作可以改变根元素是什么。例如,在您执行第一次插入之前,根元素可能是 NULL。像红黑树这样的平衡树在插入后偶尔需要打乱,这会改变根的值。

它还可以使一些操作更方便,例如在更大的表达式中立即使用新的根值:

if ( (newroot = insert( root, val )) == NULL )
  // error on insert
else
  // do something with newroot

返回根值的另一种方法是传递一个指针并修改参数:

void insert( struct node **root, int val )
{
  if ( !*root )
    *root = new_node( val );
  else
    ...
}

答案 1 :(得分:0)

插入可能会改变树的根,应该设置为“根”引用。
最好的例子是'插入第一个节点将使其成为根节点';

另一种方法是声明类似
apt install python3-dev
注意传递的“指向节点*的指针”,它可以改变调用者的引用而不是返回“新根”

void insert_elements(struct node** root, int val);

答案 2 :(得分:0)

文件范围内的这个声明

struct node *root;

通过NULL初始化指针根。

现在在这个电话中

insert_elements(root, val)

指针根值的副本被传递给函数。即参数是按值传递的。该函数处理文件作用域中定义的指针根的副本。

在函数内更改副本不会影响原始指针root。所以在函数调用之后,指针 root 仍然具有值 NULL

因此函数返回函数内动态分配节点的新指针,该节点将分配给文件作用域中定义的指针根。

root = insert_elements(root, val);

另一种方法是通过引用将指针 root 传递给函数。在 C 中,通过引用传递意味着通过指向它的指针间接传递一个对象。因此该函数可以像例如

void insert_elements(struct node **root, int val);

并称为喜欢

insert_elements( &root, val );

在这种情况下,在函数内取消引用指向指针根的指针(即取消引用函数参数),您将直接访问文件作用域中定义的指针 root 并可以在函数内更改它.

为了清楚起见,请考虑以下演示程序。

#include <stdio.h>
#include <stdlib.h>

void f( int *p )
{
    p = malloc( sizeof( int ) );
    
    *p = 20;
}

int main(void) 
{
    int x = 10;
    int *px = &x;
    
    printf( "Before the call of f *px = %d\n", *px );
    
    f( px );
    
    printf( "After  the call of f *px = %d\n", *px );

    return 0;
}

程序输出为

Before the call of f *px = 10
After  the call of f *px = 10

如你所见,main 中定义的指针 px 没有改变。您可以通过以下方式想象函数调用和函数定义

f( px );

//...

void f( /* int *p */ )
{
    int *p = px;

    p = malloc( sizeof( int ) );
    
    *p = 20;
}

即参数p由函数参数px的值初始化,然后用动态分配的内存地址重新分配参数。参数 px 未更改。