提问人:Surya Majumder 提问时间:2/28/2022 最后编辑:Vlad from MoscowSurya Majumder 更新时间:2/28/2022 访问量:328
结构指针的单指针或双指针
Single or Double Pointer for Struct pointers
问:
我试图编写一些代码来检查调用函数时结构指针的指针函数。
我尝试对树或链表使用单指针,但发现通常如果我编写一个 void 函数并且 head 或 root 不是全局的,它会给我带来分割错误。
我找到的唯一解决方案是返回 head(或 root) 的值,或者如果我不想返回任何内容(但需要调用 &),则使用双指针。
我的代码是:
//This one gives Segmentation Error always.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
void addnode(node *head, node *tail, int d)
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = d;
newnode->next = NULL;
if(head==NULL)
{
head = tail = newnode;
}
else
{
tail->next = newnode;
tail = newnode;
}
}
//This one also works [but sometimes gives Segmentation Error (No Idea why)]. But it has a return
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
void addnode(node *head, node *tail, int d)
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = d;
newnode->next = NULL;
if(head==NULL)
{
head = tail = newnode;
}
else
{
tail->next = newnode;
tail = newnode;
}
return head;
}
//This one also works fine but here I don't need to return anything.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
void addnode(node **head, node **tail, int d) // Here head and tail is called with & eg: addnode(&head1,&tail1,data);
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = d;
newnode->next = NULL;
if(head==NULL)
{
*head = *tail = newnode;
}
else
{
(*tail)->next = newnode;
*tail = newnode;
} //No return
}
我的问题是为什么会发生这个错误?难道我们不需要在需要时使用指针,甚至使用变量 从一个只能有一个返回语句的函数中具有多个值?
除了关于单指针和双指针之外,我们是否也使用数组指针进行第一种情况,甚至在数组(或任何其他指针类型)中,当我们执行 *arr1 = *arr2 时; 那么修改 arr1 不会修改 arr2(因为现在它们指向相同的数据)?如果是这样的话,为什么我需要在这里使用双指针来修改和访问它们?
我真的很困惑。
请帮忙。
答:
此功能
void addnode(node *head, node *tail, int d)
处理原始指针值的副本并用作参数表达式。更改副本不会影响原始指针。head
tail
此功能
void addnode(node *head, node *tail, int d)
{
//...
return head;
}
具有返回类型。因此,编译器应发出错误消息,因为如果函数的返回类型为 ,则返回语句不应返回值。void
void
但是,如果您将按以下方式声明该函数
node * addnode(node *head, node *tail, int d)
{
//...
return head;
}
然而,它会遇到与第一个函数相对于指针相同的问题,因为该函数将再次处理原始指针的副本,并且指针的新值不会返回给调用方。tail
tail
此函数的定义
void addnode(node **head, node **tail, int d) // Here head and tail is called with & eg: addnode(&head1,&tail1,data);
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = d;
newnode->next = NULL;
if(head==NULL)
{
*head = *tail = newnode;
}
else
{
(*tail)->next = newnode;
*tail = newnode;
} //No return
}
有一个错误。而不是这个 if 语句
if(head==NULL)
你必须写
if ( *head == NULL )
该函数之所以工作,是因为指针 和 通过指向它们的指针通过引用传递给函数。因此,取消引用指针,例如在此语句中head
tail
*head = *tail = newnode;
您可以直接访问原始指针(而不是处理原始指针值的副本)并可以更改它们。
但无论如何,你的方法并不好。
您应该声明另一个将包含指针的结构,例如head
tail
typedef struct list
{
node *head;
node *tail;
} list;
然后在 main 中,您可以声明一个结构类型的对象,例如
list list1 = { .head = NULL, .tail = NULL };
在本例中,函数将如下所示addnode
int addnode( list *lst, int data )
{
node *newnode = malloc( sizeof( node ) );
int success = newnode != NULL;
if ( success )
{
newnode->data = data;
newnode->next = NULL;
if ( lst->head == NULL )
{
lst->head = newnode;
}
else
{
lst->tail->next = newnode;
}
lst->tail = newnode;
}
return success;
}
并且该函数可以像例如一样调用
addnode( &list1, data );
或
if ( !addnode( &list1, data ) )
{
puts( "Error. Not enough memory" );
}
评论
下一个:从函数向全局结构赋值
评论