草庐IT

关于struct:C 带结构的双向链表

codeneng 2023-03-28 原文

C Doubly linked list with structure

我正在做一个双向链表。据我所知,它正在工作,但来到这里是为了确保并查看我是否以正确的方式进行操作。

另一方面,当我做这个时,我遇到了其他与双向链表无关的问题,但与 C 文件之间的结构和"可见性"有关。如果您了解我应该对这两个其他疑问提出其他问题,请告诉。否则请随时启发我。

在我的 file1.c 我有这个:

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
#include <stdlib.h>

typedef struct team{
    char *name;
    char *teamPlace;
}Team;

typedef struct nodeTeam{
    int numberOfTeams;
    Team team;
    struct nodeTeam *next;
    struct nodeTeam *prev;
}NodeTeam;

int createsListOfTeams(NodeTeam **head, NodeTeam **tail);
void printListOfTeams(NodeTeam *listofTeams);
int addNodeTeamsSorted(NodeTeam *head, NodeTeam **tail, Team team);

int main()
{
    NodeTeam *headEquipas,*tailEquipas;
    Team eq;
    /*Creates the doubly linked list*/
    if(createsListOfTeams(&headEquipas,&tailEquipas)){
        printf("\
Error\
"
);
        return 0;
    }
    /*Add the teams to the doubly linked list. At the end, all teams will be sorted by name*/
    eq.name ="D team";
    eq.teamPlace ="D team place";
    if (addNodeTeamsSorted(headEquipas,&tailEquipas,eq)){
        printf("\
Error\
"
);
        return 0;
    }

    eq.name ="A team";
    eq.teamPlace ="A team place";
    if (addNodeTeamsSorted(headEquipas,&tailEquipas,eq)){
        printf("\
Error\
"
);
        return 0;
    }

    eq.name ="C team";
    eq.teamPlace ="C team place";
    if (addNodeTeamsSorted(headEquipas,&tailEquipas,eq)){
        printf("\
Error\
"
);
        return 0;
    }

    eq.name ="B team";
    eq.teamPlace ="B team place";
    if (addNodeTeamsSorted(headEquipas,&tailEquipas,eq)){
        printf("\
Error\
"
);
        return 0;
    }

    /*Will print all the teams*/
    printListOfTeams(headEquipas);

    return 0;
}

在我的 file2.c 上有这个

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    typedef struct team{
        char *name;
        char *teamPlace;
    }Team;

    typedef struct nodeTeam{
        int numberOfTeams;
        Team team;
        struct nodeTeam *next;
        struct nodeTeam *prev;
    }NodeTeam;

    /*Add the teams to the doubly linked list. At the end, all teams will be sorted by name*/
    int createsListOfTeams(NodeTeam **head, NodeTeam **tail){
        (*head) = (NodeTeam *)malloc(sizeof(NodeTeam));

        if ((*head) == NULL){
            return -1;
        }
        (*head)->numberOfTeams = 0;
        (*head)->team.teamPlace ="";
        (*head)->team.name ="";
        (*head)->next = NULL;
        (*head)->prev = NULL;

        *tail = *head;
        return 0;
    }

    /*Creates the doubly linked list*/
    int addNodeTeamsSorted(NodeTeam *head, NodeTeam **tail, Team team){
        NodeTeam *no,*listIni;


        no = (NodeTeam*) malloc(sizeof(NodeTeam));
        if (no == NULL){
            return -1;
        }

        /*copy of my list*/
        listIni = head;

        no->team = team;
        /*to see is it's the first element of my list*/
        if(head->numberOfTeams == 0)
        {
            no->next = head->next;
            no->prev = head;
            head->next = no;
            *tail = no;

        }
        else{ /*If not the first element*/
            head = head->next;
            while(head->prev != *tail && strcmp(head->team.name,no->team.name) < 0 && strcmp((*tail)->team.name,no->team.name)>0){
                head = head->next;
                (*tail) = (*tail)->prev;
            }
            if(strcmp(head->team.name,no->team.name) >= 0 || head->prev == *tail){
                no->next = head;
                no->prev = head->prev;
                (head->prev)->next = no;
                head->prev = no;

            }
            else if(strcmp((*tail)->team.name,no->team.name) <= 0){
                no->next = (*tail)->next;
                no->prev = (*tail);
                (*tail)->next = no;
                *tail = no;

            }
        }

        /*Updates the number of element of the list*/
        head = listIni;
        head->numberOfTeams++;

        return 0;
    }
    /*Prints my lists*/
    void printListOfTeams(NodeTeam *listofTeams){
        printf("|   number of teams %22d |\
"
,listofTeams->numberOfTeams);
        printf("|      team name      |        team place      |\
"
);
        printf("--------------------------------------------------\
"
);
        listofTeams = listofTeams->next;
        while (listofTeams != NULL){
            printf("| %-21s | %-22s |\
"
,listofTeams->team.name,listofTeams->team.teamPlace);
            listofTeams = listofTeams->next;
        }
        printf("--------------------------------------------------\
\
"
);
    }

这是我的树问题:

Q1 - 这是实现双向链表的正确方法吗?头和尾分别指向列表的开头和结尾?

Q2 - 为什么要在我的两个文件上声明 struct teamstruct nodeTeam?既然它们都在同一个项目中,那么声明不应该对我项目中的所有文件都"可见"吗?

Q3 - 在 struct team 为什么我必须声明 char *name 而不是 char name[31]

  • C 中没有"项目"之类的东西,只有"翻译单元"。
  • Q1 看起来不错,但大多数非英语名称让我不愿意仔细检查,抱歉 :-)。 Q2 将其放入头文件中。 Q3 没有人知道你为什么必须......快速回答是你不知道。
  • @keltar。对不起。忘记翻译了:(现在翻译了
  • 1 努力正确地写出问题:)


在您之前的评论和更仔细地分析了您的代码之后,我做了一些修改。
我错误地解释了关于头部和尾部项目的一个评论,虽然你正在设计一个循环列表

  • 我花时间复制/粘贴/编译您的代码。虽然它几乎可以工作,但我必须说我会用

    以另一种方式设计

    • prev/ next 指针移动到 struct team
    • 并将 nodeTeamteam 成员替换为指向第一个 teamhead 指针。

    这将有以下好处:

    • 防止为每个 nodeTeams 重复但仅对第一个有意义的 numberOfTeams 浪费无用的空间
    • 避免概念上的 head 和实际的第一团队之间的混淆

    通过将团队列表中的指针值与

    相加

    printf("| %-21s | %-22s | %p - p=%p n=%p\
    ",listofTeams->team.name, listofTeams->team.teamPlace, listofTeams, listofTeams->prev, listofTeams->next);

    我注意到您的链接中可能存在错误:

    | A team | A team place | 0x101d00980 - p=0x101d00920 n=0x101d009e0

    | B team | B team place | 0x101d009e0 - p=0x101d00980 n=0x101d009b0

    | C team | C team place | 0x101d009b0 - p=0x101d00980 n=0x101d00950

    | D team | D team place | 0x101d00950 - p=0x101d009b0 n=0x0

    你可以看到next指针没问题,但是prev指针显示可疑重复(0x101d00920确实是'head')。

    如果您跟踪代码的执行并检查它在 addNodeTeamsSorted() 中所做的事情,您可能会注意到在第 3 步之前一切正常(在现有 A 之后添加团队 C

    • 谢谢。我的链接有问题。不知道怎么解决。列表应该是这样的。我的列表的头元素为 numberOfTeams,其值为 4(A、B、C 和 D 团队)。 Team teamnameteamPlace""。 next 指针指向 A team,prev 指针指向 NULLA team 下一个指向 B teamB team 下一个指向 C teamC team 下一个指向 D team,因为 D team 是我列表的最后一个元素,所以 D team 下一个应该指向到 NULL
    • A team prev 指向我列表的头元素,B team prev 指向 A teamC team prev 指向 B team,并且由于 D team 是我列表的最后一个元素,D team prev应该指向 C team。因此,正如您在打印调试中所展示的那样,我的列表中间的 prev 链接存在问题。如果我的头元素的地址是 0x101d00920,那么 A team prev 就可以了
    • 我已经更深入地研究了它并更正了我对第 1 点的解释
    • 非常感谢您的时间和耐心。

  • 有关关于struct:C 带结构的双向链表的更多相关文章

    1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

      我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

    2. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

      给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

    3. ruby-on-rails - 一般建议和推荐的文件夹结构 - Sinatra - 2

      您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应

    4. ruby-on-rails - 关于 Ruby 的一般问题 - 2

      我在我的rails应用程序中安装了来自github.com的acts_as_versioned插件,但有一段代码我不完全理解,我希望有人能帮我解决这个问题class_eval我知道block内的方法(或任何它是什么)被定义为类内的实例方法,但我在插件的任何地方都找不到定义为常量的CLASS_METHODS,而且我也不确定是什么here,并且有问题的代码从lib/acts_as_versioned.rb的第199行开始。如果有人愿意告诉我这里的内幕,我将不胜感激。谢谢-C 最佳答案 这是一个异端。http://en.wikipedia

    5. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

      我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

    6. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

      按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

    7. ruby-on-rails - 在 Rails 中存储(结构化)配置数据的位置 - 2

      对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化

    8. ruby - 关于 Ruby 中 Dir[] 和 File.join() 的混淆 - 2

      我在Ruby中遇到了一个关于Dir[]和File.join()的简单程序,blobs_dir='/path/to/dir'Dir[File.join(blobs_dir,"**","*")].eachdo|file|FileUtils.rm_rf(file)ifFile.symlink?(file)我有两个困惑:首先,File.join(@blobs_dir,"**","*")中的第二个和第三个参数是什么意思?其次,Dir[]在Ruby中有什么用?我只知道它等价于Dir.glob(),但是,我对Dir.glob()确实不是很清楚。 最佳答案

    9. ruby-on-rails -/usr/local/lib/libz.1.dylib,文件是为 i386 构建的,它不是被链接的体系结构 (x86_64) - 2

      在我的mac上安装几个东西时遇到这个问题,我认为这个问题来自将我的豹子升级到雪豹。我认为这个问题也与macports有关。/usr/local/lib/libz.1.dylib,filewasbuiltfori386whichisnotthearchitecturebeinglinked(x86_64)有什么想法吗?更新更具体地说,这发生在安装nokogirigem时日志看起来像:xslt_stylesheet.c:127:warning:passingargument1of‘Nokogiri_wrap_xml_document’withdifferentwidthduetoproto

    10. elasticsearch源码关于TransportSearchAction【阶段三】 - 2

      1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>

    随机推荐