为什么我们在使用函数时需要return指针?
Why we need to return pointer when we use function?
我正在尝试编写代码以使用函数 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
中returning根指针,为什么我们不将函数returning值更改为[=14] =] 和 return 没什么!
大王不胜感激
插入可能会更改树的根,应设置为“根”引用。
最好的例子是 'inserting the first node will make it the root node';
另一种方法是声明类似
的内容
void insert_elements(struct node** root, int val);
注意传递的“指向节点*的指针”,它可以更改调用者的引用而不是返回“新根”
node* myTree;
insert_element(&myTree, xVal);
通常你会做类似的事情,因为插入操作可以改变根元素是什么。例如,在执行第一次插入之前,根元素可能是 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
...
}
这个声明在文件范围内
struct node *root;
通过NULL
初始化指针root。
现在正在通话中
insert_elements(root, val)
指针根值的副本被传递给函数。也就是说参数是按值传递的。该函数处理文件范围内定义的指针根的副本。
在函数内更改副本不会影响原始指针root
。所以在函数调用之后,指针 root 的值仍然是 NULL
.
因此函数 returns 函数内动态分配节点的新指针将分配给文件作用域中定义的指针根。
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
未更改。
我正在尝试编写代码以使用函数 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
中returning根指针,为什么我们不将函数returning值更改为[=14] =] 和 return 没什么!
大王不胜感激
插入可能会更改树的根,应设置为“根”引用。
最好的例子是 'inserting the first node will make it the root node';
另一种方法是声明类似
的内容
void insert_elements(struct node** root, int val);
注意传递的“指向节点*的指针”,它可以更改调用者的引用而不是返回“新根”
node* myTree;
insert_element(&myTree, xVal);
通常你会做类似的事情,因为插入操作可以改变根元素是什么。例如,在执行第一次插入之前,根元素可能是 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
...
}
这个声明在文件范围内
struct node *root;
通过NULL
初始化指针root。
现在正在通话中
insert_elements(root, val)
指针根值的副本被传递给函数。也就是说参数是按值传递的。该函数处理文件范围内定义的指针根的副本。
在函数内更改副本不会影响原始指针root
。所以在函数调用之后,指针 root 的值仍然是 NULL
.
因此函数 returns 函数内动态分配节点的新指针将分配给文件作用域中定义的指针根。
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
未更改。