当一个指针传递给一个结构作为参数,当一个指针传递给一个指针指向一个结构? [英] When to pass a pointer to a structure as an argument, and when to pass a pointer to a pointer to a structure?

查看:110
本文介绍了当一个指针传递给一个结构作为参数,当一个指针传递给一个指针指向一个结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是在问候以下code。

My question is in regards to the following code.

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

struct node
{
    int v;
    struct node * left;
    struct node * right;
};

typedef struct node Node;

struct bst
{
    Node * root;
};

typedef struct bst BST;

BST * bst_insert(BST * tree, int newValue);
Node * bst_insert_node(Node * node, int newValue);
void bst_traverseInOrder(BST * tree); 
void bst_traverseInOrderNode(Node * node);

int main(void)
{
    BST * t;

    bst_insert(t, 5);
    bst_insert(t, 8);
    bst_insert(t, 6);
    bst_insert(t, 3);
    bst_insert(t, 12);

    bst_traverseInOrder(t);

    return 0;
}

BST * bst_insert(BST * tree, int newValue)
{
    if (tree == NULL)
    {
        tree = (BST *) malloc(sizeof(BST));
        tree->root = (Node *) malloc(sizeof(Node));
        tree->root->v = newValue;
        tree->root->left = NULL;
        tree->root->right = NULL;

        return tree;
    }

    tree->root = bst_insert_node(tree->root, newValue);
    return tree;
}

Node * bst_insert_node(Node * node, int newValue)
{
    if (node == NULL)
    {
        Node * new = (Node *) malloc(sizeof(Node));
        new->v = newValue;
        new->left = NULL;
        new->right = NULL;
        return new;
    }
    else if (newValue < node->v)
        node->left = bst_insert_node(node->left, newValue);
    else
        node->right = bst_insert_node(node->right, newValue);

    return node;
}

void bst_traverseInOrder(BST * tree)
{
    if (tree == NULL)
        return;
    else
    {
        bst_traverseInOrderNode(tree->root);
        printf("\n");
    }
}

void bst_traverseInOrderNode(Node * node)
{
    if (node == NULL)
        return;
    else
    {
        bst_traverseInOrderNode(node->left);
        printf("%d ", node->v);
        bst_traverseInOrderNode(node->right);
    }
}

因此​​,code完美的作品原样。它将正确插入每个值成BST和穿越功能将遍历树序正确。然而,当我最初宣布吨至是BST(例如第27行),如果我还可以指派吨至为NULL(例如BST * T = NULL),然后插入不工作了。但是,如果我再重新分配吨的第一个插入(例如T = bst_insert(T,5)),然后一切再次工作。是否有特定的原因?

So, the code works perfectly as is. It will insert each value into BST correctly, and the traversal function will traverse the tree inorder correctly. However, when I am initially declaring t to be a BST (e.g. line 27), if I also assign t to be NULL (e.g. BST * t = NULL), then the insertion does not work anymore. But, if I then reassign t for the first insertion (e.g. t = bst_insert(t, 5)), then everything works again. Is there a particular reason for this?

其次,我怎么知道什么时候我需要一个指针传递给一个指针指向一个结构?如果我想改变这种状况 INT I 点,那么我就需要&放传递的价值;我来的函数,是否正确?但是,如果我想结构节点内改变n的值,那么为什么我需要通过 **节点一个函数,而不仅仅是 *节点

Secondly, how do I know when I need to pass a pointer to a pointer to a structure? If I want to change the value that int i points to, then I need to pass &i to a function, correct? But if I want to change the values within struct node n, then why do I need to pass a **node to a function, and not just a *node?

感谢你这么多的考虑看看。

Thank you so much for taking a look.

推荐答案

在C,的所有的是按值传递,没有例外。

In C, everything is passed by value, there is no exception to this.

您可以的的emulate 的传递按引用传递指针,在函数解引用它,但是这是一个难兄难弟真正传递通过引用。

You can emulate pass-by-reference by passing the pointer and dereferencing it in the function but this is a poor cousin to real pass-by-reference.

底线是,如果你想改变的任何的传递给函数,你必须提供其指针非关联化,并为改变指针本身,这意味着通过指针的指针。需要注意的是:

The bottom line is, if you want to change anything passed to a function, you have to provide its pointer for dereferencing and, for changing pointers themselves, that means passing the pointer of the pointer. Note that:

t = modifyAndReturn (t);

是不是真的同样的事情 - 本身不会修改功能 T ,它只是返回的东西其中的主叫的然后分配给 T

is not really the same thing - the function itself does not modify t, it simply returns something which the caller then assigns to t.

所以,你已经做了后者的方式,在那里你可以做这样的事情:

So, you've done it the latter way, where you can do something like this:

int add42 (int n) { return n + 42; }
:
x = add42 (x);

使用模拟传递通过引用,这将是(指针和提领):

Using the emulated pass-by-reference, that would be (with pointers and dereferencing):

void add42 (int *n) { *n += 42; }
:
add42 (&x);

有关改变指针,正如前面提到的,您需要将指针传递到指针。比方说,你想改变一个char指针,它指向下一个字符。你会做这样的事情:

For changing pointers, as mentioned earlier, you need to pass the pointer to the pointer. Let's say you want to change a char pointer so that it points to the next character. You would do something like:

#include <stdio.h>

void pointToNextChar (char **pChPtr) {
    *pChPtr += 1;              // advance the pointer being pointed to.
}

int main (void) {
    char plugh[] = "hello";
    char *xyzzy = plugh;
    pointToNextChar (&xyzzy);
    puts (xyzzy);              // outputs "ello".
}


C ++实际上提供的正确的传递由参考使用&安培; 修改,如:


C++ actually provides proper pass-by-reference with the & "modifier" such as:

void add42 (int &n) { n += 42; }

和你不必再担心函数内derefencing,任何更改都立即回显到原来传递的参数。我倒是希望C21都会有这样的功能,这将节省很多麻烦的人不熟悉,我们必须用C忍受指针体操: - )

and you don't have to then worry about derefencing within the function, any changes are immediately echoed back to the original passed parameter. I rather hope that C21 will have this feature, it will save a lot of trouble for people unfamiliar with the pointer gymnastics we have to endure in C :-)

顺便说一句,你只能用code一个相当严重的问题。在,行

By the way, you have a rather serious problem with that code. Within main, the line:

BST * t;

将设置 T 来这是不太可能你想要的任意值。您的的设置它最初为NULL,这样 bst_insert 正确初始化它。

will set t to an arbitrary value which is unlikely to be what you want. You should set it initially to NULL so that bst_insert correctly initialises it.

这篇关于当一个指针传递给一个结构作为参数,当一个指针传递给一个指针指向一个结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆