当一个指针传递给一个结构作为参数,当一个指针传递给一个指针指向一个结构? [英] When to pass a pointer to a structure as an argument, and when to pass a pointer to a pointer to a structure?
问题描述
我的问题是在问候以下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屋!