繁体   English   中英

关于函数和链表中的指针的说明(C)

[英]Clarification about pointers in functions and linked list (C)

我在我的程序中实现链表时遇到了麻烦,我想我遇到的问题之一是指针,指向指针的指针等,因为 function,我会尝试更好地解释我:我有一个节点定义为

struct node{
    char* data; 
    struct node* next;
}

我有一个 insert_node function 定义为struct node* Insert_Node(struct node *head, struct node* to_insert)从 Create_Node function 获取to_insert定义为

struct node Create_Node(char* to_create) {
   struct node *newNode = NULL;
   newNode = (struct node *) malloc(sizeof(struct node));
   newNode->data = malloc(sizeof(to_create) + 1);
   strcpy(newNode->data, to_create);
   newNode->next = NULL;
   return *newNode;
}

还有一个名为 Delete_Node 的Delete_Node定义为int Delete_Node(struct node** head, char* to_delete) 然后我有一个名为 Free_All 的Free_All来删除定义为void Free_All(struct node** head)的整个列表;

这些函数既被调用到主函数中,也被调用到其他函数中,函数被调用为

struct node* head = NULL;    
*newNode = Create_Node(word);
head = Insert_Node(head,newNode);   (Function with only one *)

*newNode = Create_Node(word);

Free_All(&head);   (Function with two **)

相反,在函数中,它们被称为

int Delete_Node(struct node** head, char* to_delete){
while (*head != NULL && strcmp((*head)->data, to_delete) != 0 ){
    head = &(*head)->next;
}
int ok = *head != NULL;
if (ok){
    struct node *tmp = *head;
    *head = (*head)->next;
    free(tmp);
}
return ok;
}

似乎插入 function 效果很好(如果我打印列表,我的所有单词都很好),但是我在删除 function (它不会删除正确的单词)和其他使用指针的函数(比如如果我在列表中搜索一个词我总是得到“不存在”,即使这个词存在)并且我得到 SIGSEGV 和 EXC_BAD_ACCESS ...

我哪里错了?

我复制了您的代码位并尝试了各种功能。 在测试和微调各种功能后,我最终得到了以下代码片段。

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

struct node
{
    char* data;
    struct node* next;
};

struct node* Create_Node(char* to_create)
{
    struct node* newNode = NULL;
    newNode = (struct node *) malloc(sizeof(struct node));
    newNode->data = malloc(strlen(to_create) + 1);
    strcpy(newNode->data, to_create);
    newNode->next = NULL;
    return newNode;
}

void Insert_Node(struct node *head, struct node* to_insert)
{
    struct node * work = head;

    while (work->next != NULL)
    {
        work = work->next;
    }

    work->next = to_insert;
}

void print_list(struct node *head)
{
    struct node * work;
    work = head;

    while(work != NULL)
    {
        printf("Node data: %s\n", work->data);
        work = work->next;
    }
}

int Delete_Node(struct node* head, char* to_delete)
{
    struct node *work, *tmp;
    work = head;
    int ok = 0;

    while (1)
    {
        tmp = work->next;
        if (tmp != NULL)
        {
            if (strcmp(tmp->data, to_delete) == 0)
            {
                printf("Removing node\n");
                tmp = work->next;
                work->next = tmp->next;
                free(tmp);
                ok = 1;
                break;
            }
        }
        if (work->next == NULL)
        {
            break;
        }
        work = work->next;
    }

    return ok;
}

int main()
{
    char name[32];

    struct node * head = NULL;
    struct node * work = NULL;
    head = Create_Node("Head");

    for (int i = 0; i < 4; i++)
    {
        sprintf(name, "%s %d", "List#", i+1);
        work = Create_Node(name);
        Insert_Node(head, work);
    }

    print_list(head);

    if (Delete_Node(head, "List# 3"))
    {
        printf("Deletion successful\n");
    }

    print_list(head);

    return 0;
}

你会注意到,我在“print_list”中添加了一个 function 来证明链表已经到位,同时也证明了指定列表条目的删除发生了。 重要的调整是使用节点的工作变量,然后沿着“下一个”节点链向下移动。

以下是运行此测试代码的示例 output。

@Una:~/C_Programs/Console/StructureNodes/bin/Release$ ./StructureNodes 
Node data: Head
Node data: List# 1
Node data: List# 2
Node data: List# 3
Node data: List# 4
Removing node
Deletion successful
Node data: Head
Node data: List# 1
Node data: List# 2
Node data: List# 4

试一试,看看它是否符合您的代码精神。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM