简体   繁体   English

为什么使用function需要返回指针?

[英]Why we need to return pointer when we use function?

I'm trying to write a code to insert nodes in binary search tree using a function insert_elements .我正在尝试编写代码以使用 function insert_elements在二叉搜索树中插入节点。 In my textbook the code for the function is-在我的教科书中,function 的代码是-

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;
}

I don't understand why we are returning the root pointer in the function insert_elements , why we don't change the function returning value to void and return nothing!我不明白为什么我们要在 function insert_elements中返回根指针,为什么我们不将 function 返回值更改为void并且什么都不返回! Will be grateful for any king of help.将不胜感激任何国王的帮助。

Usually you do something like that because the insert operation can change what the root element is.通常你会做类似的事情,因为插入操作可以改变根元素是什么。 For example, the root element may be NULL until you perform the first insert.例如,在执行第一次插入之前,根元素可能是NULL A balanced tree like a red-black tree occasionally needs to be shuffled after an insert, which changes the value of the root.像红黑树这样的平衡树偶尔需要在插入后进行洗牌,这会改变根的值。

It can also make some operations more convenient, like immediately using that new root value in a larger expression:它还可以使某些操作更加方便,例如在更大的表达式中立即使用新的根值:

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

An alternative to returning the root value is to pass a pointer and modify the parameter:返回根值的替代方法是传递一个指针并修改参数:

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

an insert might change the root of the tree and should be set to the "root" reference.插入可能会更改树的根,因此应设置为“根”引用。
Best example is 'inserting the first node will make it the root node';最好的例子是“插入第一个节点将使它成为根节点”;

another way to do that is declare something like另一种方法是声明类似
void insert_elements(struct node** root, int val);
note the "pointer to node*" passed, that can change the caller's reference instead of returning the "new root"注意传递的“指向节点*的指针”,它可以更改调用者的引用而不是返回“新根”

node* myTree;
insert_element(&myTree, xVal);

This declaration in the file scope此声明在文件 scope 中

struct node *root;

initialize the pointer root by NULL .通过NULL初始化指针根。

Now in this call现在在这个电话中

insert_elements(root, val)

a copy of the value of the pointer root is passed to the function. That is the argument is passed by value.根指针的值的副本被传递给function。也就是说参数是按值传递的。 The function deals with a copy of the pointer root defined in the file scope. function 处理文件 scope 中定义的指针根的副本。

Changing the copy within the function does not influence on the original pointer root .更改 function 中的副本不会影响原始指针root So after the function call the pointer root will still have the value NULL .所以在 function 调用之后,指针 root 的值仍然是NULL

So the function returns the new pointer of a dynamically allocated node within the function that will be assigned to the pointer root defined in the file scope.因此 function 返回 function 中动态分配节点的新指针,该节点将分配给文件 scope 中定义的指针根。

root = insert_elements(root, val);

Another approach is to pass the pointer root to the function by reference.另一种方法是通过引用将指针 root 传递给 function。 In C passing by reference measn passing an object indirectly through a pointer to it.在 C 中,通过引用传递意味着通过指向它的指针间接传递 object。 So the function can be declared like for example所以 function 可以像这样声明

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

and called like并称呼

insert_elements( &root, val );

In this case dereferencing the pointer to the pointer root (that is dereferencing the function parameter) within the function you will get a direct access to the pointer root defined in the file scope and can change it within the function.在这种情况下,取消引用 function 中指向指针根的指针(即取消引用 function 参数),您将直接访问文件 scope 中定义的指针root ,并可以在 function 中更改它。

To make it clear consider the following demonstrative program.为了清楚起见,请考虑以下演示程序。

#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;
}

The program output is程序 output 是

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

As you see the pointer px defined in main was not changed.如您所见,main 中定义的指针 px 没有更改。 You can imagine the function call and the function definition the following way您可以通过以下方式想象 function 调用和 function 定义

f( px );

//...

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

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

That is the parameter p is initialized by the value of the function argument px and then the parameter is reassigned with the address of the dynamically allocated memory. The argument px was not changed.即参数p由 function 参数px的值初始化,然后用动态分配的 memory 的地址重新分配参数。参数px没有改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM