Code Bye

问题多多…链表的第一个节点就没连上去…求指导…

如题……本人先把本人的代码发来,烦请各位不吝挑错找问题,一点点指导助本人完成这部分的学习,不胜感谢!
数据结构:
typedef struct node{
    int id;
    char name[255];
    double value;
    struct node *next;
}NODE;

然后设置了一个初始化函数,写值的工作就都放在这了:

int init_node(NODE *node){
    short int stat = -1;
    printf("\nNODE ADDR 0x%p...\n",node);/*这个本人用来查询当前地址,后面本人会写明这样做的原因*/
    printf("\n\nPLEASE FILL THIS FORM:\nID >>> ");
    scanf("%d",&node->id);
    printf("NAME >>> ");
    scanf("%s",node->name);
    printf("VALUE >>> $");
    scanf("%lf",&node->value);
    printf("NODE INFORMATION INITLIZED.\n\n");
    stat = 0;
    return stat;
}

原因是node是指针,所以针对node的更改就相当于对需要初始化的数据做了修改。这样把返回值设置成int也可以观察能否执行时有错误——其实本人不知道能否能做到,原因是即便stat一直都是-1,假如函数中途中断了,return出来的就不一定是几了……
另外,printf(“\nNODE ADDR 0x%p…\n”,node);这句是为了验证本人究竟修改或显示的是哪个变量,在代码中出现很多次,大家就当是本人调试BUG的时候给本人参考的值就好了……
表头方面本人创建的是不保存数据的那种:

NODE *create_head(){
    NODE *HEAD = (NODE *)calloc(sizeof(NODE),1);
    if(HEAD == NULL)return HEAD;
    HEAD->next = NULL;
    return HEAD;
}

本人想先写一个在末尾新增数据的函数,本人的意思就是从head开始一点点屡,当走到next是空的时候,就把这个位置的next指向新节点,原因是新节点是最后一个了,所以新节点的next就是空。
原理大致照着这个思路图写的:

int append_node(NODE *HEAD){
    NODE *temp,*current=HEAD;
    while(current->next){
        current = current->next;
    }
    temp = (NODE *)calloc(sizeof(NODE),1);
    if(temp == NULL)return -1;
    printf("\nNODE ADDR 0x%p...\n",temp);
    temp->next = NULL;
    init_node(temp);
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    current->next = temp;
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    current=current->next;
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    return 0;
}

然后是简单的显示全部表内容的函数:
大致就是只要当前节点不是空就通过print_node打印出来,print_node本人就不挂上来了,没啥意义……

void list(NODE *HEAD){
    if(count(HEAD)<=1){
        printf("YOU DO NOT HAVE ANY NODE IN TABLE.");
        return;
    }
    NODE *current = HEAD;
    while(current->next){
        print_node(current);
        current=current->next;
    }
}

这里面的count是为了跳过head的,过程就是一直current=current->next,假如current是空了,就把计数器累加的值返回来:

int count(NODE *HEAD){
    NODE *current = HEAD;
    int count = 0;
    while(current){
        count++;
        current=current->next;
    }
    return count;
}

然后本人就迫不及待的尝试了:

#include "chaintabl.h"
int main()
{
    NODE *head = create_head();
    list(head);
    if(!append_node(head)==0){
        printf("APPEND FAILED!");
        return 1;
    }
    list(head);
    free(head->next);
    free(head);
    return 0;
}

本人的目的就是首先创建一个头,假如head只有本人,原因是它各内容都是空的,所以就不打印,直接显示“这个链表还没有任何节点信息。”
然后本人通过append增加之后再把整个表list出来,按说应该会输出“10086,badass,100.86”这种信息,结果实际运行后发现居然新节点里面都是空的值……
然后本人就增加了很多个

printf("\nNODE ADDR 0x%p...\n",node);

以寄希望看看是不是本人把地址给错了,或参数传的有问题,结果如下:

然后本人就懵了……
这个0028FE70是个什么鬼?……
之前说好的003F1360呢?……003F36E8呢?……
问一下这到底是怎么回事?
=========================================================
本人再总结一下本人的问题:
1、之前传入的参数还有append函数中处理的命名都是003F36E8,为什么第一个节点的地址变成了0028FE70了?
2、本人append的写法有问题么?
3、本人的思路图存在问题么?
4、init_node这里有什么问题么?
5、本人还都应该注意什么?
6、本人的哪个方面基础还需要增强?

解决方案

15

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
    int id;
    char name[255];
    double value;
    struct node *next;
}NODE;
int init_node(NODE *node)
{
    short int stat = -1;
    printf("\nNODE ADDR 0x%p...\n", node);
    printf("\n\nPLEASE FILL THIS FORM:\nID >>> ");
    scanf("%d",&node->id);
    printf("NAME >>> ");
    scanf("%s",node->name);
    printf("VALUE >>> $");
    scanf("%lf",&node->value);
    printf("NODE INFORMATION INITLIZED.\n\n");
    stat = 0;
    return stat;
}
NODE *create_head()
{
    NODE *HEAD = (NODE *)calloc(sizeof(NODE), 1);
    if (!HEAD) {
        fprintf(stderr, "malloc error!\n");
        exit(-1);
    }
    HEAD->next = NULL;
    return HEAD;
}
int append_node(NODE *HEAD)
{
    NODE *temp, *current = HEAD;
    while (current->next)
        current = current->next;
    temp = (NODE *)calloc(sizeof(NODE), 1);
    if(!temp)
        return -1;
    printf("\nNODE ADDR 0x%p...\n", temp);
    temp->next = NULL;
    init_node(temp);
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    current->next = temp;
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    current = current->next;
    printf("\ncurrent: 0x%p...\n",current);
    printf("\ncurrent->next: 0x%p...\n",current->next);
    return 0;
}
int count(NODE *HEAD)
{
    NODE *current = HEAD;
    int count = 0;
    while(current){
        count++;
        current = current->next;
    }
    return count;
}
static void print_node (NODE *pcur)
{
    printf("id = %d\t name = %s\t value = %lf\n",
           pcur->id, pcur->name, pcur->value);
}
void destroy_nodes(NODE *phead)
{
    NODE *p = phead->next, *q;
    while (p) {
        q = p->next;
        free(p);
        p = q;
    }
}
void delete_head(NODE *phead)
{
    free(phead);
}
void list(NODE *HEAD)
{
    NODE *current = HEAD->next;
    if (count(HEAD) <= 1) {
        printf("YOU DO NOT HAVE ANY NODE IN TABLE.");
        return;
    }
    while (current) {
        print_node(current);
        current = current->next;
    }
}
int main()
{
    NODE *head = create_head();
    list(head);
    if(append_node(head)){
        printf("APPEND FAILED!");
        return 1;
    }
    list(head);
    destroy_nodes(head);
    delete_head(head);
    return 0;
}

改了一些地方,试一下

5

首先不认同楼上的观点,calloc是在堆上分配,题主这样返回地址是可以的
本人直接拿你云盘里的代码进行验证,编译有个fprintf的警告,运行结果没问题

30

刚刚看见,不知道题主还在吗?上面本人说的有错误,原因是昨天时间紧急,你的calloc是可以为头结点分配内存的,刚刚本人用vs试了一下你的代码,就是你发帖的代码,你的代码可以编译成功,但是运行的时候输入确有问题,出现在
scanf("%s", &node->name);

链表里面的东西是不能这样赋值的,即使是int float可以用scanf,给链表的内容赋值你可以先建立一个数组a[255],然后scanf(“%s”,a);strcpy(node->name,a);这样才可以。
其他地方本人试了没有出问题,至于你的头结点地址的问题本人没有遇见,或许是我们俩的编译器不同,本人修改了赋值语句之后全部的代码都可以成功运行,并且分配数据。
以上的代码是本人成功运行在vs上面的,希望题主试一下。

15

temp = (NODE *)calloc(sizeof(NODE), 1);
这一句 对calloc()函数的运用有误,应该是calloc(1,sizeof(NODE)) 吧

5

还是试着尽量用calloc()函数吧,可以初始化。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明问题多多…链表的第一个节点就没连上去…求指导…