【问题标题】:Is the address of a var in c passed by value?c中var的地址是按值传递的吗?
【发布时间】:2020-04-28 12:19:42
【问题描述】:

这是从主函数传递变量的方式:

Node merged = NULL; 
ErrorCode result = mergeSortedLists(left, right, &merged);

这是函数的签名。

ErrorCode mergeSortedLists(Node list1, Node list2, Node *merged_out); 

如果func发生错误。 mergesortedlists 我们应该返回 res=Error 并且合并的列表应该是 NULL

导师说我们应该分配merged_out=NULL; 但是地址不是按值传递给函数的吗?我们不应该将它指向的 var 分配给 NULL 即 *merged_out=NULL;

提前致谢!

【问题讨论】:

  • 首先显示名称 Node 是如何声明的。

标签: c linked-list pass-by-reference function-declaration


【解决方案1】:

一切在 C 中通过值传递。

所以是的,&merged(一个指针)按值传递给mergeSortedLists。换句话说,merged_out 指向的对象可以通过指针引用在该函数中更改,但该函数中指针值的任何更改都不会反映在调用者中。

我不确定你的导师为什么要你在函数本身中写*merged_out = NULL。为此,merged_out 必须是指向指针的指针,并在调用站点进行适当的更改。

【讨论】:

  • @adlinat:不是从调用者的角度来看你的函数,不。
  • 从上下文来看,Node 很可能是指向结构的指针,所以Node * 参数是指向指针的指针,merged_out 可能就是那个参数。
  • @EricPostpischil:你希望如此。这个答案的唯一用途可能是第一句话。
【解决方案2】:

看来Node这个名字是指针类型的别名。

类似

typedef struct node
{
    //...
} *Node;

所以在这段代码中sn-p

Node merged = NULL; 
ErrorCode result = mergeSortedLists(left, right, &merged);

变量merged 是一个指针。并且是通过引用函数mergeSortedLists来传递的。

为指针类型引入这样的别名是个坏主意,因为它只会使代码的读者感到困惑。

如果接受名称 Node 是指针类型的别名(例如

typedef struct node *Node;

然后这个函数声明

ErrorCode mergeSortedLists(Node list1, Node list2, Node *merged_out); 

等价于

ErrorCode mergeSortedLists( struct node  *list1, struct node *list2, struct node **merged_out); 

也就是说三个参数都有指针类型。

【讨论】:

  • "passed by reference":这个词不应该被使用,C 中没有通过引用传递。
  • 我知道 C,别担心。这是一个 C++ 术语。阅读this 以及该问题的其他答案。
  • @Jabberwocky 你既不懂 C 也不懂 C++。通过引用传递是一个通用术语,它意味着通过使用某种机制间接传递对象。在每种语言中,机制的实现可能不同。在 C 中,通过引用传递这个术语意味着通过指向它的指针间接传递一个对象。
  • @Jabberwocky 即使在 C# 中,该术语也有两个含义。您可以通过引用传递对象,也可以使用说明符 ref 按引用传递引用,例如在 Java 中不存在。
  • @Jabberwocky:C 标准讨论了引用和取消引用。 C++ 将“引用”重新定义为 C++ 语言中的一个特定功能这一事实并没有废除该词在其他上下文中的先前含义。
【解决方案3】:

节点合并 = NULL; 合并是指向用户定义结构的指针。 (由 typedef 运算符完成) 例如:

struct S_Node{
    int m_var;
    struct S_Node* p_m_next;
};
typedef struct S_Node* Node;  /*now Node is new type. its pointer to S_Node*/

所以 merged_out 是指向指针的指针。因此,如果函数出现错误,我们在这段代码 sn-p 中将其设置为 NULL:

ErrorCode mergeSortedLists(Node list1, Node list2, Node *merged_out)
{
    if(!list1 || !list2) /*lets assume that this is the error case*/
    {
        *merged_out=NULL;
        return Error;
    }
}

【讨论】:

  • Re“ 这个语句在 C 中无效。因为指针就像 c 中的任何其他变量一样(按值传递),并且在你的函数中分配它(mergeSortedLists)将分配它的副本。因此,为了分配它,您需要指针的地址,...”:在此之前引用的代码确实通过指针分配;它是*merged_out=NULL;,而不是merged_out=NULL;
  • @EricPostpischil,我修正了我的答案。我错过了一些细节。谢谢。
  • OT:通过typedef 隐藏指针是一种非常糟糕的编程习惯。
  • @user3629249 - 绝对!提问者需要问他的导师他为什么这样做!这是一个很坏的习惯
猜你喜欢
  • 2020-03-10
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
相关资源
最近更新 更多