【问题标题】:List of lists C列表列表 C
【发布时间】:2013-12-18 20:06:29
【问题描述】:

我想将列表由列表组成,内部列表由项目组成。

数据类型的联合:

typedef union s_datatype {
    int t_int;
    char* t_char;
    double t_double;
    bool t_bool;
} t_datatype;

项目结构:

typedef struct s_token {
    int y;
    int type;
    t_datatype value;
    struct s_token *next;
} t_token;

内部列表的结构:

typedef struct s_line {
    int x;
    int depth;
    int type;
    int number_of_tokens;
    t_token*head;
    struct s_line *next;
} t_line;

最终名单的结构:

typedef struct s_tokenized_code {
    int number_of_lines;
    t_line*head;
} t_tokenized_code;

假设我想添加新的“行”并在该行中插入“令牌”。但我不知道,如何把它放在一起。你能帮助我吗?我不确定如何分配它以及如何使用这个列表列表。

编辑:结构修改

【问题讨论】:

  • 先从一个简单的单一列表开始,以获得想法。
  • ...并且不要将指针隐藏在 typedef 后面。它只会让你和其他人感到困惑。
  • 您似乎缺少的东西:当您创建列表的头部时,您通常也希望它是一个指针。我想你可以让它完全形成,但是你必须有不同的代码才能访问列表的第一个元素。例如,t_line * headt_token * head。这与@wildplasser 评论不要将 typedef 放在指针上直接相关。
  • @Johan Nelson 所以我应该删除 typedef 之前的指针,然后在你说的地方添加指针,对吗?
  • 当我听到“list of a list”时,这让我想起了一些可以像矩阵一样结构化的东西,例如,想象头节点(比如结构节点{})分布在每列的开头然后每个节点也有 Node{ Nodenext} 但还包括一个下面的节点: struct Node {Node next; Node* below},这是否有助于设想您尝试做什么?

标签: c linked-list


【解决方案1】:

已解决。

如果您想知道,如何(我想将项目插入到列表的末尾,而不是开头):

t_token*init_token (int y, int type, t_datatype value) {
    t_token*token = malloc(sizeof(struct s_token));
    if (token == NULL) {
        return NULL;
    }
    token->y = y;
    token->type = type;
    token->value = value;
    token->next = NULL;
    return token;
}

t_line*init_line (int x, int depth, int type) {
    t_line*line = malloc(sizeof(struct s_line));
    if (line == NULL) {
        return NULL;
    }
    line->x = x;
    line->depth = depth;
    line->type = type;
    line->number_of_tokens = 0;
    line->head = NULL;
    line->next = NULL;
    return line;
}

t_tokenized_code*init_code (void) {
    t_tokenized_code*code = malloc(sizeof(struct s_tokenized_code));
    if (code == NULL) {
        return NULL;
    }
    code->number_of_lines = 0;
    code->head = NULL;
    return code;
}

void insert_token (t_line*line, t_token*token) {
    if (token != NULL) {
        if (line->head == NULL){
            line->head = token;
            line->number_of_tokens += 1;
            return;
        }
        t_token*tmp = line->head;
        while (tmp->next != NULL) {
            tmp = tmp->next;
        }
        tmp->next = token;
        line->number_of_tokens += 1;
    }
}

void insert_line (t_tokenized_code*code, t_line*line) {
    if (line != NULL) {
        if (code->head == NULL) {
            code->head = line;
            code->number_of_lines += 1;
            return;
        }
        t_line*tmp = code->head;
        while (tmp->next != NULL) {
            tmp = tmp->next;
        }
        tmp->next = line;
        code->number_of_lines += 1;
    }
}

void free_code (t_tokenized_code*source) {
    if (source == NULL) {
        return;
    }
    t_line*line;
    t_token*token;
    while ((line = source->head) != NULL) {
        while ((token = line->head) != NULL) {
            line->head = token->next;
            free(token);
        }
        source->head = line->next;
        free(line);
    }
    free(source);
}

让我们做一个简单的测试 - 第一行添加 2 个标记,第二行添加 3 个标记:

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

int main (void) {
    t_tokenized_code*source = init_code();
    t_line*line = init_line(0,0,3);
    if (line == NULL) {
        return 1;
    }
    insert_line(source, line);
    t_datatype tt;

    tt.t_char = "first";
    t_token*token = init_token(0,6, tt);
    if (token == NULL) {
        return 1;
    }
    insert_token(line, token);

    tt.t_char = "second";
    token = init_token(1,6, tt);
    insert_token(line, token);

    line = init_line(1,0,3);
    insert_line(source, line);

    tt.t_char = "third";
    token = init_token(0,6, tt);
    insert_token(line, token);

    tt.t_char = "fourth";
    token = init_token(1,6, tt);
    insert_token(line, token);

    tt.t_char = "fifth";
    token = init_token(2,6, tt);
    insert_token(line, token);

    line = source->head;
    while (line != NULL) {
        printf("****\n");
        token = line->head;
        while (token != NULL) {
            printf("%s\n", token->value.t_char);
            token = token->next;
        }
        line = line->next;
    }
    free_code (source);
    return 0;
}

输出如下:

****
first
second
****
third
fourth
fifth

【讨论】:

  • 为什么大部分代码使用typedef名称t_token,而malloc下的sizeof却使用struct s_token?与t_linet_tokenized_code 相同。为什么不一致?
  • 另外,在最初的问题中,您说过要添加新行并将标记插入该新行。在您发布的答案中,我没有看到您“添加新行”。那么,如何“解决”呢?
  • 所以sizeof(t_token)sizeof(struct s_token) 一样吗?解决方法是调用init_code()返回初始化代码,然后init_line(..)返回行,现在我们需要将行添加到结构中:insert_line(..)然后我们需要初始化令牌init_token(..)并将令牌添加到行insert_token(..)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
相关资源
最近更新 更多