【问题标题】:how to take a linked list and a function pointer as inputs如何将链表和函数指针作为输入
【发布时间】:2019-07-22 09:31:59
【问题描述】:

我是 C 新手,正在尝试学习函数指针。我应该完成“map_list”函数,它接受一个链表和一个函数指针,并以相同的顺序返回一个新列表,但包含所有值平方。请指出我做错的地方。

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


struct Link {
    struct Link *next;
    int value;
};

void print_list(struct Link *list) {
    for(struct Link *l = list; l != NULL; l = l->next) {
        printf("%d", l->value);

        if(l->next) {
            printf(", ");
        }
    }

    printf("\n");
}


struct Link *append(int x, struct Link *head) {
    struct Link *head_ = (struct Link*)malloc(sizeof(struct Link));
    head_->next = head;
    head_->value = x;

    return head_;
}

struct Link *reverse_list(struct Link *list) {
    struct Link *head = NULL;

    for(struct Link *l = list; l != NULL;) {
        struct Link *next = l->next;
        l->next = head;
        head = l;

        l = next;
    }

    return head;
}

struct Link *map_list(struct Link *link_list,int (*Square)(int)   ) {

    struct Link *new_list = NULL;
    new_list = new_list ->next;
    new_list ->value = (*Square)(link_list ->value);
    return new_list;
}

int square(int x) {
    return x * x;
}

int add3(int x) {
    return x + 3;
}



struct Link *theList() {
    struct Link *l = append(1, NULL);
    l = append(2, l);
    l = append(3, l);
    l = append(5, l);
    return l;
}

int main() {


    struct Link *l = theList();
    print_list(map_list(l, &square));
    ;
    return 0;
}

我收到“分段错误(核心转储)”

【问题讨论】:

  • 想想struct Link *new_list = NULL;new_list = new_list -&gt;next;这行。这将如何运作?而对于函数的其余部分,如何在不进行任何迭代的情况下创建(或修改原始列表)新列表?
  • OT: about: struct Link *head_ = (struct Link*)malloc(sizeof(struct Link)); 1) 返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱,使其更难以理解、调试等。2) 始终检查 (!=NULL) 返回值以确保操作成功。
  • 关于:struct Link *reverse_list(struct Link *list) { 你的问题没有提到任何关于颠倒列表顺序的内容,那么为什么要使用这个功能?请发帖minimal reproducible example
  • OT:包含未使用的头文件是一种非常糟糕的编程习惯:建议删除语句:#include &lt;stdbool.h&gt;#include &lt;string.h&gt;#include &lt;ctype.h
  • OT:参数和变量名称应指明contentusage(或两者兼有)像l 这样的名称毫无意义,即使在当前上下文中也是如此

标签: c list function declaration singly-linked-list


【解决方案1】:

如果我理解正确,您在编写函数map_list 时会遇到一些麻烦。 它可以如下所示

struct Link * map_list( const struct Link *link_list, int operation( int )   ) 
{
    struct Link *new_list  = NULL;
    struct Link **new_node = &new_list;

    for ( const struct Link *current = link_list; current != NULL; current = current->next )
    {
        *new_node = malloc( sizeof( struct Link ) );

        ( *new_node )->next  = NULL;
        ( *new_node )->value = operation( current->value );

        new_node = &( *new_node )->next;
    } 

    return new_list;
}

并且可以像这样调用该函数

map_list( l, square );

map_list( l, add3 );

该函数不检查节点的内存分配是否成功。您可以自己添加这样的检查。

至于你自己的函数实现

struct Link *map_list(struct Link *link_list,int (*Square)(int)   ) {

    struct Link *new_list = NULL;
    new_list = new_list ->next;
    new_list ->value = (*Square)(link_list ->value);
    return new_list;
}

那么对于初学者来说,它具有未定义的行为

ew_list = new_list ->next;

并且相对于分配没有意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    相关资源
    最近更新 更多