如何在C中使用void函数修改指针

huangapple go评论100阅读模式
英文:

how to modify pointers with a void function in C

问题

我正在尝试构建一个函数,用于在二叉搜索树(BST)中搜索用户提供的值(整数键),我提供了下面的函数。基本上,它的作用或应该的作用是搜索键,如果找到它,它应该修改 "found" 指针并将包含键的节点传递给它,然后应该找到键的前驱和后继,并将它们传递给 "pre" 和 "suc"。

这是该函数:

void findPreSuc(struct node *root, struct node* found, struct node* pre, struct node* suc, int key)
{
    // 基本情况
    if (root == NULL){  
        return ;
    }
    // 如果键存在于根节点
    if (root->data == key)
    {
        found=root;
        printf("\n%d",found->data); // 测试根节点是否传递给 found
        // 左子树中的最大值是前驱
        if (root->left_child != NULL)
        {
            struct node* tmp = root->left_child;
            while (tmp->right_child){
                tmp = tmp->right_child;
                pre = tmp ;
            }
        }
 
        // 右子树中的最小值是后继
        if (root->right_child != NULL)
        {
            struct node* tmp = root->right_child;
            while (tmp->left_child){
                tmp = tmp->left_child;
                suc = tmp ;
            }
        }
        return ;
    }
 
    // 如果键小于根的键,转向左子树
    if (root->data > key)
    {
        suc = root ;
        findPreSuc(root->left_child, found, pre, suc, key) ;
    }
    else // 转向右子树
    {
        pre = root ;
        findPreSuc(root->right_child, found, pre, suc, key) ;
    }
}

当我运行下面的输入时:

int main()
{
    struct node *root=NULL;
    struct node *suc=NULL;
    struct node* pre=NULL;  
    struct node* found=NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
    findPreSuc(root, found, pre, suc, 60);
    if (found==NULL)
    {
        printf("\ndidnt work");
    }    
    return 0;
}

我得到以下输出:

60
didnt work

这意味着函数没有错误地执行,并且在其执行期间,三个指针 found、pre 和 suc 实际上被修改了(代码从 found->data 打印出了 60),但当函数结束时,指针被设置回 NULL,我得到了 "didnt work" 打印出来。有什么建议吗?

注意: 为了解决这个问题,你可能需要通过传递指向指针的指针来修改 pre、suc 和 found,以便在函数内部修改它们的值能够在函数外部保持有效。

英文:

So im trying to build a function to search in a BST a value given by the user (int key) and i came up with the function below. basically what it does, or it should do, is search the key, if it finds it it should modify the "found" pointer and pass the node where the key is to it, then should find the predecessor and successor of the key and pass them to pre and suc.

this is the function

void findPreSuc(struct node *root, struct node* found, struct node* pre, struct node* suc, int key)
{
    // Base case
    if (root == NULL){  
        return ;
    }
    // If key is present at root
    if (root->data == key)
    {
        found=root;
        printf("\n%d",found->data); //test if root node gets passed to found
        // the maximum value in left subtree is predecessor
        if (root->left_child != NULL)
        {
            struct node* tmp = root->left_child;
            while (tmp->right_child){
                tmp = tmp->right_child;
                pre = tmp ;
            }
        }
 
        // the minimum value in right subtree is successor
        if (root->right_child != NULL)
        {
            struct node* tmp = root->right_child;
            while (tmp->left_child){
                tmp = tmp->left_child;
                suc = tmp ;
            }
        }
        return ;
    }
 
    // If key is smaller than root's key, go to left subtree
    if (root->data > key)
    {
        suc = root ;
        findPreSuc(root->left_child, found, pre, suc, key) ;
    }
    else // go to right subtree
    {
        pre = root ;
        findPreSuc(root->right_child, found, pre, suc, key) ;
    }
}

when i run the inputs below

int main()
{
    struct node *root=NULL;
    struct node *suc=NULL;
    struct node* pre=NULL;  
    struct node* found=NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
    findPreSuc(root, found, pre, suc, 60);
    if (found==NULL)
    {
        printf("\ndidnt work");
    }    
    return 0;
}

i get this output

60
didnt work

it means the function gets executed with no errors and during its execution the 3 pointers found, pre and suc do actually get modified (the code prints 60 from the found->data) but when the function ends the pointers get set back to NULL and i get the "didnt work" print
any advice?

答案1

得分: 2

要修改传递给函数的任何指针,您需要传递指向指针的指针

示例:

void foo(char **x)
{
    *x = "foo";
}

int main(void)
{
    char *bar = "bar";
    
    printf("bar is: '%s'. 调用函数 `foo` ... \n", bar);
    foo(&bar);
    printf("现在 bar 是: '%s'\n", bar);
}

https://godbolt.org/z/MW9caaMWz

英文:

To modify any pointer passed to the function you need to pass pointer to pointer.

Example:

void foo(char **x)
{
    *x = "foo";
}

int main(void)
{
    char *bar = "bar";
    
    printf("bar is: '%s'. Calling the function `foo` ... \n", bar);
    foo(&bar);
    printf("Now bar is: '%s'\n", bar);
}

https://godbolt.org/z/MW9caaMWz

huangapple
  • 本文由 发表于 2023年7月31日 19:18:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803107.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定