将节点添加到链表的开头

Adding node to the beginning of Linked List

我正在尝试操作链表,任务是将节点添加到链表的开头。

fl_newEmpty() 函数 returns 一个指向 空表,不知道自己写的对不对

fl_show() 只打印每个节点

我应该得到以下输出。地址可以不同

------- Show floatList : list made by FL_add ---------
0 : 0x7fad88404c10 7.000000 0x7fad88404c00
1 : 0x7fad88404c00 5.000000 0x7fad88404bf0
2 : 0x7fad88404bf0 3.000000 0x0
3 elements in all.

但我明白了:我不知道为什么 2 索引中的节点指向 3 索引中的节点:(

------- Show floatList : list made by FL_add ---------
0   : 0x1e1a2c0 7.000000 0x1e1a2a0
1   : 0x1e1a2a0 5.000000 0x1e1a280
2   : 0x1e1a280 3.000000 0x1e1a260
3   : 0x1e1a260 0.000000 (nil)
4 elements in all

我的代码:

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

struct floatList
{
    float val;
    struct floatList *next;
};

void FL_show(struct floatList *plist, char *label)
{
    // check if plist is empty
    if (plist == NULL)
    {
        printf("The list is empty!\n");
    }

    struct floatList *pf;
    pf = plist;

    int count = 0; // for checking the total number of elements in the list
    printf("------- Show floatList : %s ---------\n", label);
    for(int i = 0 ; pf!= NULL ; i++){
        count++;
        printf("%d\t: %p %f %p\n",i, pf, pf->val, pf->next);
        pf = pf->next;
    }
    printf("%d elements in all\n",count);
}

struct floatList *FL_newEmpty()
{
    struct floatList *new_list = (struct floatList *)malloc(sizeof(struct floatList));
    new_list->next = NULL;
    return new_list;
}

struct floatList* FL_add(struct floatList *plist, float val)
{
    struct floatList *new_list = (struct floatList*)malloc(sizeof(struct floatList));
    new_list->next = plist;
    new_list->val = val;
    return new_list;
}



int main(){

    struct floatList *plist;
    plist = FL_newEmpty();
    plist = FL_add(plist,3);
    plist = FL_add(plist,5);
    plist = FL_add(plist,7);
    FL_show(plist,"list made by FL_add");
    return 0;

}

额外的节点是因为完全不必要的功能 FL_newEmpty() 您已添加到您的程序并正在使用。

干脆删除这个函数,不要再调用了。

int main(){
    struct floatList *plist;
    plist = FL_add(NULL,3);
    plist = FL_add(plist,5);
    plist = FL_add(plist,7);
    FL_show(plist,"list made by FL_add");
    return 0;
}

空指针已经是你的空列表;您可以使用 FL_add(NULL, 3) 添加到它。不需要创建新空列表的构造函数,因为只有一个空列表:值 (struct floatList *) 0。这只是一个空指针,不需要分配内存。如果你愿意,你可以为它制作一个宏:

#define NULL_FLOATLIST ((struct floatList *) NULL)

然后:

plist = FL_add(NULL_FLOATLIST, 3.0);

如果某个倒霉的 CS 讲师强制要求有一个 FL_newEmpty() 函数,我们可以这样提供:

#define FL_newEmpty() ((struct floatList *) NULL)

或作为一个简单的函数:

struct floatList *FL_newEmpty()
{
    return NULL;
}

但是,名称中的 new 一词显然具有误导性;它总是返回相同的空指针!

您看到的 (nil) 语法而不是 0x00000000 只是您特定 C 库的 %p 转换说明符的一个功能。我知道 GNU C 库以这种方式打印空指针,也许还有其他方式。 C 标准没有指定 %p 的输出是什么样的;它说 s:

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

如果您想看到一致的 0x 表示法,您可以将指针转换为 intptr_t,然后使用 PRIxPTR 转换说明符打印该值:

#include <inttypes.h>

...

    printf("%d\t: 0x%" PRIxPTR " %f 0x%" PRIxPTR "\n", i,
           (intptr_t) pf, pf->val, (intptr_t) pf->next);

PRIxPTR<inttypes.h> 的一个宏,它扩展为适合 intptr_t 值的转换说明符,用于将其呈现为十六进制。这是必需的,因为 intptr_t 是一个 typedef 名称;我们不知道它是什么整数类型。该宏不提供前导 % 字符,仅提供转换说明符本身。在我们的示例中,我们可以看到为什么它有用:我们可以在 % 之后偷偷加入 # 修饰符以获得 0x 前缀。

顺带一提,FL_newempty函数不仅没有用,而且还有一个问题:初始化浮点数据失败。您在输出中看到的 0.0 只是侥幸,因为内存从 malloc 中以全零字节出现,malloc 不能保证。