由于 question 被标记为 C 和 C++,因此从这个角度看一下不同之处。这个答案不涉及 C++ 容器类或智能指针,这在 C++ 代码中通常应该是首选。下面是 4 种情况,两种可以修改调用者的结构和调用者的指针,两种只能修改给定结构的内容。
C++修改指针
当您希望函数修改指针并将指针值返回给 C++ 中的调用者时,您可以使用对指针的引用来执行此操作:
void clearNode(struct node *&n){
n->field = 0; // modify caller's struct
n = nullptr; // set caller's pointer to NULL (C++11)
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // OK, np becomes null, n.field becomes 0
clearNode(&np); // will not compile, &np is not right type
clearNode(&n); // will not compile, &n is not lvalue
C修改指针
在 C 中,相同的代码将是这样的(也适用于 C++,尽管上面的版本会更好更干净):
void clearNode(struct node **n){
(*n)->field = 0; // modify caller's struct
*n = NULL; // set caller's pointer to NULL
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // will not compile, np is not right type
clearNode(&np); // OK, np becomes NULL, n.field becomes 0
clearNode(&n); // will not compile, &n is not of right type
C只修改结构
但是如果我们只用指针编写相同的代码,它的工作方式会有点不同:
void clearNode(struct node *n){
n->field = 0; // modify caller's struct
n = NULL; // change local parameter, which in this case has no effect anywhere
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // OK, except np is not modified, n.field becomes NULL
clearNode(&np); // will not compile, &np is not of right type
clearNode(&n); // OK, n.field becomes NULL
C++ 只修改结构
最后,C++ 中的相同代码这样会更干净:
void clearNode(struct node &n){
n.field = 0; // modify caller's struct
// no pointer, nothing to set to NULL
}
...
struct node n; // value
struct node *np = &n; // pointer to node
clearNode(np); // will not compile, np is not of right type
clearNode(&np); // will not compile, &np is not of right type
clearNode(&n); // will not compile, &n is not of right type
// these work, n.field becomes 0:
clearnode(n);
clearnode(*np);
你的问题
因此,从上面可以看出,如果您需要修改调用者指针,请将指针传递给指针(C 和 C++)或引用指针(C++)。这是有代价的:你必须总是传递一个可修改的指针变量,而且双间接也有很小的开销。两者的语法如上所示。
如果您不需要修改调用者指针,但需要修改 struct 内容,请将指针(C 和 C++)或引用(C++)传递给 struct。两者的语法如上所示。
第三种情况,当您不需要修改任何内容时,上面没有介绍,但有 3 个基本替代方案:按值传递(C 和 C++,干净的语法但复制整个结构),通过指向 const 的指针传递(C 和 C++,有点丑陋的语法,但只传递地址)或通过 const 引用传递(仅限 C++,语法简洁,只传递地址)。
总而言之,当您需要修改调用者的指针时,使用双指针(或对指针的引用)。否则,传递一个指针(或引用),如果 struct 很小,甚至传递一个值。