通过值和引用将c中struct类型的指针传递给函数

时间:2014-05-28 14:53:35

标签: c linked-list

好吧,我知道一个事实,即将指针传递给结构作为函数的参数使得参数的行为就好像它是通过值传递的,只是对于结构的特殊情况。 因此,如果我要在链接列表中对head ptr进行任何修改,则在被调用函数中所做的更改将不会反映在调用fnt中,但我的问题是是否对任何后续节点进行了更改。被调用函数中的s指针反映在调用函数中。例如,如果我要说从头指针i通过使用单指针而不是双指针传递的链接列表的开头删除第五个节点,那么列表从函数返回包含已删除的元素还是不包含它?

好的另一个例子: 在下面的代码中递归删除链接列表中的替代元素,不会失败,因为参数是* head而不是** head?

void deleteAlt(struct node *head)
{
  if (head == NULL)
    return;

  struct node *node = head->next;

  if (node == NULL)
    return;

  /* Change the next link of head */
  head->next = node->next;   

  /* free memory allocated for node */
  free(node);

  /* Recursively call for the new next of head */
  deleteAlt(head->next);
}

4 个答案:

答案 0 :(得分:4)

  

我知道一个事实,即将指针传递给结构作为函数的参数使得参数的行为就好像是通过值传递的,只是结构的特殊情况。

这根本不是真的。指针本身如果通过值传递(因为每个参数都在C中),但指针引用的变量不会被复制。在函数中更改它将在调用者中更改它,因为它是相同的结构。

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

struct S {
   int i;
};

void f(struct S* s) {
   s->i = 456;
}

int main() {
   struct S* s = malloc(sizeof(struct S));
   s->i = 123;
   printf("%d\n", s->i);
   f(s);
   printf("%d\n", s->i);
   free(s);
   return 0;
}

$ gcc -o a a.c && a
123
456

  

确定另一个例子:在下面的代码中以递归方式删除链接列表中的备用元素,不会失败,因为参数是*head而不是**head < / p>

没有。由于deleteAlt永远不会修改head,因此无需更新其调用者的head,因此无需将指针传递给调用者的head

答案 1 :(得分:2)

通过值传递的结构的指针表现为按值传递的整个结构显然为真。

顺便说一句,C不会 “通过引用传递”。您可以将指针传递给某个东西,但 按值传递。

答案 2 :(得分:0)

如果您传递了指向链接列表的指针并对其进行了修改(删除了元素),则删除的值将在调用者的上下文中删除。

他们需要的最简单的原因(struct node ** head)是因为修改了你需要它的地址。如果您要删除某些内容(在这种情况下为* head),您将需要其地址。您要修改的任何内容都需要其地址。

答案 3 :(得分:0)

要删除节点,必须重定向上一个节点的下一个指针,使其指向下一个节点而不是当前节点。由于我们没有指向前一个节点的指针,因此我们无法重定向其下一个指针。那我们该怎么办?

我们可以通过将数据从下一个节点移动到当前节点然后删除下一个节点来轻松逃脱。

此解决方案具有O(1)运行时。这里有一些代码来说明这个简单的逻辑。

void deleteNode( Node * node )
{
    Node * temp = node->next;
    node->data = node->next->data;
    node->next = temp->next;
   free(temp);
}

需要考虑的一些事项。

这种方法可能会带来潜在的问题。

例如,让我们考虑一下链接列表A - &gt; B - &gt; C - &gt; D和我们得到一个指向B的指针来删除它。

Theoretically, you would expect B to be deleted and all pointers which were pointing to   B to become invalid.

However, if we use this function to delete B, all pointers which were pointing to B will still be valid. Furthermore, node B now will contain the value C and node C will be invalid.

Any previous pointers to C will become invalid, which may not be expected behavior in general. This is not a problem if there are no external links to any of the items in the linked list.

但这肯定是你应该考虑让你的面试官展示你的思考过程。

For proper understanding working of deleting an element from the linklist please refer following link :

https://www.cs.bu.edu/teaching/c/linked-list/delete/

指针是地址变量,即它们包含地址,因此如果指针传递给函数,则传递实际值本身。

在对其执行任何操作时,将修改该值。在您的情况下,它将被删除。