Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在C中传递结构参数时使用双指针?_C_Pointers_Linked List - Fatal编程技术网

为什么在C中传递结构参数时使用双指针?

为什么在C中传递结构参数时使用双指针?,c,pointers,linked-list,C,Pointers,Linked List,我正在编写一些C代码来实现基本的堆栈数据结构操作,如push、pop等。 我正在使用堆栈的链表实现。 在这个实现中,每次我将一个值推入到“卡住”节点中时,我都会创建一个新节点,并将其设置为链接列表的头节点。因此,这涉及到更改头部节点的引用 void push(stack **t, int ele) { stack *new, *temp; temp=*t; new=(stack *)malloc(sizeof(stack)); if(new==NULL) { printf("\n sta

我正在编写一些C代码来实现基本的堆栈数据结构操作,如push、pop等。 我正在使用堆栈的链表实现。 在这个实现中,每次我将一个值推入到“卡住”节点中时,我都会创建一个新节点,并将其设置为链接列表的头节点。因此,这涉及到更改头部节点的引用

void push(stack **t, int ele)
{
stack *new, *temp;
temp=*t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=*t;
*t=new;

}
如果我使用单指针编写类似的代码,那么它将是这样的

void push(stack *t, int ele)
{
stack *new, *temp;
temp=t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=t;
t=new;

}
在函数中,除此之外的所有步骤中,头节点(**t)都显示在分配的右侧

 *t=new;
基本上,第一个代码将'new'分配给**t的指针,即*t,第二个代码将'new'分配给*t的指针,即t。 两者似乎都只需要将指向头部节点的单个指针指定为“new”,但只有第一个代码起作用,而第二个代码实际上并不修改头部节点的值


发生这种情况的原因是什么?为什么第二个代码的工作方式与第一个不一样?

因为C中的所有内容都是通过值传递的。因此,如果需要为函数的参数指定一个新值,则必须添加一个间接级别。如果没有,则只接收本地副本,因此分配给该副本的任何值将仅在函数本身中可见

另一方面,不要在C中强制转换
malloc
的返回值。这是不必要的,会使您的代码混乱,并且可能会隐藏允许默认int的编译器的错误

在。。另一个旁注,而不是写以下内容:

new_stack = malloc(sizeof(stack));
改用这个:

new_stack = malloc(sizeof(*new_stack));

现在,如果
新堆栈的类型发生变化,您就不会有问题了。

如果是单指针,那么

int addInBeginning(int *s)
{
 ... // add a node in the beginning of the linked list
}

int main()
{
 int *t;
 ... // make t point to a linked list say t ---> 1 -> 2 -> 3
 f(t);
}
最初,s和t指向同一个列表。但是当我们在开始添加一个节点时,s指向新节点,而t仍然指向它之前指向的节点。当push返回时,新节点无法从t访问

0 -> 1 -> 2 -> 3
^    ^
|    |
s    t
如果是双指针,s将指向t,而t又指向列表。所以所有指针操作都发生在原始指针t上

s ----> t ----> 0 -> 1 -> 2 -> 3

您需要修改传递给
push()
的第一个堆栈元素的指针,因此需要一个指针类型的参数。在第二个函数中,
t
的赋值在函数外部是不可见的。是不是在第二个代码中,函数只是复制指向堆栈的指针,并且函数执行的所有更改仅应用于副本?请注意,不要使用名为
new
(或
删除
)你可能会认为你永远不会把C++转换成C++,但是如果这样做,你会通过避免C++的关键字来简化事情。编码这个。这些变量名似乎更简单。谢谢!!是的,gcc编译器似乎能检测出转换错误,但是,是的,替代代码显然更好