为什么结构指针的值错误 和使用2个函数的main版本测试程序链接列表结构

问题描述

因此,我开始研究C语言中的数据结构,并希望编写一个单链表。

这只是其中的一小部分:

struct nodes {
    int val;
    struct nodes *next;
};

void insert(struct nodes *list,int val) {
    struct nodes *tmp = (struct nodes*) malloc(sizeof(struct nodes));
    tmp->val = val;
    tmp->next = list;
    list = tmp;
}

int main() {
    struct nodes *test;
    insert(test,5);
    insert(test,10);

    printf("test %d\n",test->next->val);
}

这里我得到完全错误输出。当我尝试编写不需要传递结构指针的函数时,它的工作原理与预期的一样。

输出

test 90053

P.S我仍然从C开始,所以不要太刻苦:D

解决方法

您正在更改局部变量,因此对调用方没有影响。您可能的意思是使用指向指针的指针,以便可以对其进行更改:

var url = `Mysite:3000/from/here/${othervars}?orgId=1&refresh=30s`

现在的功能如下:

int main() {
    struct nodes *test = NULL; // Don't forget to initialize
    insert(&test,5);
    insert(&test,10);

    printf("test %d\n",test->next->val);
}

由于void insert(struct nodes **list,int val) { struct nodes *tmp = malloc(sizeof(struct nodes)); // No need to cast malloc() in C tmp->val = val; tmp->next = *list; *list = tmp; } 被取消引用(list),因此实际上更改了原始值(指向),这意味着列表头发生了更改。

在您的原始代码中,您从未初始化过*list,这只是一些随机的垃圾值,并且由于list永远无法更改它,因此它仍然是垃圾数据。通过这种方式访问​​任何数据都是未定义的行为,因此您将得到垃圾数据或崩溃。

,

您可以这样:

    struct nodes {
    int val;
    struct nodes* next;
};

nodes* insert(struct nodes* list,int val) {
    struct nodes* tmp = (struct nodes*)malloc(sizeof(struct nodes));
    tmp->val = val;
    tmp->next = list;
    return tmp;
}

在尝试编写类似第一个函数的结构时,我相信---是list()而不是insert()。

在每个可以更改列表起始地址的功能中,您必须返回地址,否则它将丢失。而且由于您仅在开始处插入,所以丢失了所有内容,因为开始地址始终会更改。 通常不要使用void。至少是浪费,通常是一个错误。返回一些信息,例如完成状态。查看list()的实现,该实现返回... size

int         list(struct nodes* list)
{
    struct nodes* p = list;
    int N = 0;
    while (p != NULL)
    {
        printf("#%d  %d\n",N,p->val);
        p = p->next; N += 1;
    };
    printf("\n");
    return N;
}

和使用2个函数的main()版本

int main() {
    struct nodes* test = NULL;
    int n = 0;
    for(n = 800; n>0; n-= 100) test = insert(test,n);
    n = list(test);
    printf("At the end list() returned %d\n",n);
}

这样,您可以从一开始就获得更多信息。

#0  100
#1  200
#2  300
#3  400
#4  500
#5  600
#6  700
#7  800

At the end list() returned 8

测试程序

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

struct no
{
    void*       item;
    struct no*  next;
    struct no*  prev;
};  // no
typedef struct no Node;

typedef struct
{
    char* name;
    unsigned  size;
    unsigned  limit;
    Node* start;
    Node* end;
}   List;

struct nodes {
    int val;
    struct nodes* next;
};

struct nodes*   insert(struct nodes*,int);
int             list(struct nodes* L);

int main() {
    struct nodes* test = NULL;
    int n = 0;
    for(n = 800; n>0; n-= 100) test = insert(test,n);
}

struct nodes*   insert(struct nodes* list,int val) {
    struct nodes* tmp = (struct nodes*)malloc(sizeof(struct nodes));
    tmp->val = val;
    tmp->next = list;
    return tmp;
}

int         list(struct nodes* list)
{
    struct nodes* p = list;
    int N = 0;
    while (p != NULL)
    {
        printf("#%d  %d\n",p->val);
        p = p->next; N += 1;
    };
    printf("\n");
    return N;
}

如评论中所指出,请注意,列表不是node。节点集合的列表,并且节点具有数据有效负载。如果有效载荷是(void*),那么您将拥有一个真正的抽象数据结构,因为它可以加载任何内容,从单个char100-fields structure

考虑一下编写方式以及程序中有5个列表的情况:一团糟,它将变得非常快。并与下面的代码进行比较

链接列表结构

struct no
{
    void*       item;
    struct no*  next;
    struct no*  prev;
};  // no
typedef struct no Node;

typedef struct
{
    char* name;
    unsigned  size;
    unsigned  limit;
    Node* start;
    Node* end;
}   List;

请注意,随着您在List中添加更多信息,事情变得更加容易:您始终拥有大小,限制,开始和结束的指针等等

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...