有没有办法在结构中自动创建结构

时间:2021-07-28 20:17:17

标签: c struct

这段代码创建了一个“循环”,其中第一个元素指向空并指向下一个元素(如果有),如果没有,则指向空

typedef struct noeud
{
    struct noeud* point_suivant;
    struct noeud* point_precedent;
    int valeur;
    int n;

}t_noeud;
typedef struct anneau
{
    
    t_noeud* noeud;
    int nb_points;

}t_anneau;

这是 t_noeud_init

t_noeud* t_noeud_init(const int valeur) {
    t_noeud* nouveau_noeud = (t_noeud*)malloc(sizeof(t_noeud));

    if (nouveau_noeud == NULL) {
        printf("EXIT_FAILURE");
        return NULL;
    }

    nouveau_noeud->valeur = valeur;
    nouveau_noeud->point_suivant = NULL;
    nouveau_noeud->point_precedent = NULL;
    return nouveau_noeud;
}

这是 t_noeud_add

t_noeud* t_noeud_add(const int valeur, t_noeud* noeud_precedent) {
    t_noeud* nouveau_noeud = (t_noeud*)malloc(sizeof(t_noeud));
    if (nouveau_noeud == NULL) {
        printf("EXIT_FAILURE");
        return NULL;
    }
    noeud_precedent->point_suivant = nouveau_noeud;
    nouveau_noeud->valeur = valeur;
    nouveau_noeud->point_suivant = NULL;
    nouveau_noeud->point_precedent = noeud_precedent;
    return nouveau_noeud;
}

这是 t_anneau_init

t_anneau* t_anneau_init() {//remplie de zero
    t_anneau* nouveau_anneau = (t_anneau*)malloc(sizeof(t_anneau));
    if (nouveau_anneau == NULL) {
        printf("EXIT_FAILURE");
        return NULL;
    }
    
    
    nouveau_anneau->noeud = t_noeud_init(zero);     
        nouveau_anneau->noeud->n = 0;
        nouveau_anneau->nb_points = 0;
        
        nouveau_anneau->noeud->point_suivant =
        t_noeud_add(zero, nouveau_anneau->noeud); 
            nouveau_anneau->noeud->point_suivant->n = 1;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->n = 2;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->n = 3;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->n = 4;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant->n = 5;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant->point_suivant->n = 6;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    
    
    return nouveau_anneau;
}

这是一段巨大的代码,这就是为什么我想自动化它,但我尝试过的不起作用。

我尝试过这样的事情:

for (int i = 0; i < 6; i++) {
        nouveau_anneau->noeud->point_suivant = t_noeud_add(zero, nouveau_anneau->noeud);
        nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
        nouveau_anneau->noeud = nouveau_anneau->noeud->point_suivant;
    }

它可以建立在自己的基础上,但似乎无法让它发挥作用。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我认为您只需要对 for 的想法进行一些工作,也许可以试试下面的代码。我只是添加了两个辅助变量来保存当前和上一个 point_suivant

t_anneau* t_anneau_init() {//remplie de zero
    t_anneau* nouveau_anneau = (t_anneau*)malloc(sizeof(t_anneau));
    if (nouveau_anneau == NULL) {
        printf("EXIT_FAILURE");
        return NULL;
    }
        
    nouveau_anneau->noeud = t_noeud_init(zero);     
    nouveau_anneau->noeud->n = 0;
    nouveau_anneau->nb_points = 0;
        
    struct noeud* prev_point_suivant = nouveu_anneau->noeud;
    struct noeud* cur_point_suivant = prev_point_suivant->point_suivant;

    for (int i = 1; i <= 6; ++i) {
        cur_point_suivant = t_noeud_add(zero, prev_point_suivant);
        cur_point_suivant->n = i;
        ++nouveau_anneau->nb_points;

        prev_point_suivant = cur_point_suivant;
        cur_point_suivant = cur_point_suivant->point_suivant;
    }

    return nouveau_anneau;
}

答案 1 :(得分:0)

这不是一个完整的程序,但我会向您展示您可以运行的最低限度的东西,看看它是否有帮助。如果你觉得它有用,我可以用更多的常用功能来扩展它。请在评论中告诉我。

关于您的代码

如果可能,请始终提供完整的代码,以便人们可以复制和尝试。

你写的方式有点复杂,但很高兴你没有尝试将列表写成单个节点,这对初学者来说是正常的。

关于代码,我的建议(以下是你的代码的摘录,仅供评论):


nouveau_anneau->noeud = t_noeud_init(zero);     
        nouveau_anneau->noeud->n = 0;
        nouveau_anneau->nb_points = 0;
        
        nouveau_anneau->noeud->point_suivant =
        t_noeud_add(zero, nouveau_anneau->noeud); 
            nouveau_anneau->noeud->point_suivant->n = 1;
            nouveau_anneau->nb_points = nouveau_anneau->nb_points + 1;
    nouveau_anneau->noeud->point_suivant->point_suivant = 
        t_noeud_add(zero, nouveau_anneau->noeud->point_suivant); 
            nouveau_anneau->noeud->point_suivant->point_suivant->n = 2;
            nouveau_anneau->nb_points = nouveau
  • 看起来非常复杂且难以阅读。

  • 这似乎不能帮助您在列表中添加 point_ 前缀。你知道你会在代码中多次写这个,列表的代码是一个工具。代码准备好后,您将不会更改它,甚至不会经常阅读它:只需使用它来构建和管理您的链表。 列表本身的很长名称也是如此。在示例中,我使用了 A ;)

示例

我将使用您的代码,加上一些更改,并编写 3 个函数,如

typedef struct str_noeud
{
    struct str_noeud* suivant;
    struct str_noeud* precedent;
    int               valeur;

}   Noeud;

typedef struct
{
    Noeud*  debut;
    Noeud*  fin;
    int     size; // actual size
    int     maximum; // limit, or 0

}   Anneau;

Anneau* anneau_init(unsigned);
int     anneau_add(int, Anneau*);
int     anneau_list(Anneau*,const char*);

如您所料:

  • _init() 创建一个列表并返回一个指向它的指针。该参数是一个 unsigned,用于设置可以插入列表中的最大节点数。出错时返回NULL

  • _add() 在列表的开头添加一个元素。参数是值,当然还有指向列表的指针。成功返回 0 或负错误代码

  • _list() 只是列出元素。参数是列表的地址和一个可选的消息,只是为了帮助测试你是否有很多列表。

测试程序

int main(void)
{
    // fills up a list until error
    Anneau* one = anneau_init(28);
    int     value = 28;
    while (anneau_add(value--, one) == 0) {};
    anneau_list(one, "A simple test list");
    anneau_list(one, "");
    return 0;
}

这很简单:

  • 创建一个列表,限制为 28 个节点。

  • 一个循环向列表添加一个值,从 28 开始,倒计时。由于限制恰好是 28,因此当达到限制时 anneau_add() 预计会返回错误。由于元素被添加到列表的开头,我们希望看到元素 1 到 28(包括)插入到列表中。

  • 由于列表为行写下了 10 个元素,因此很容易检查。 anneau_list() 被调用两次以显示消息内容。

示例输出

A simple test list

28 [of 28 elements MAX]

    debut :    1
    fin   :   28

Elements

   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
End


28 [of 28 elements MAX]

    debut :    1
    fin   :   28

Elements

   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
End

完整的测试代码

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

typedef struct str_noeud
{
    struct str_noeud* suivant;
    struct str_noeud* precedent;
    int               valeur;

}   Noeud;

typedef struct
{
    Noeud*  debut;
    Noeud*  fin;
    int     size; // actual size
    int     maximum; // limit, or 0

}   Anneau;

Anneau* anneau_init(unsigned);
int     anneau_add(int, Anneau*);
int     anneau_list(Anneau*,const char*);


int main(void)
{
    // fills up a list until error
    Anneau* one = anneau_init(28);
    int     value = 28;
    while (anneau_add(value--, one) == 0) {};
    anneau_list(one, "A simple test list");
    anneau_list(one, "");
    return 0;
}


int         anneau_add(int v, Anneau* A)
{   // insert 'v' at the start of the list
    if (A == NULL) return -1;  // no list
    if ((A->maximum > 0) && (A->size == A->maximum)) return -2; // no space
    // ok: fits
    Noeud* one     = (Noeud*)malloc(sizeof(Noeud));
    one->valeur = v;
    one->suivant = A->debut; 
    one->precedent  = NULL; 
    A->debut       = one; // 
    A->size       += 1;
    if (A->size == 1) A->fin = one;
    return 0;
};


Anneau*     anneau_init(unsigned lim)
{ 
    Anneau* nouveau = (Anneau*)malloc(sizeof(Anneau));
    if (nouveau == NULL)
    {
        printf("EXIT_FAILURE");
        return NULL;
    }
    nouveau->debut            = NULL;
    nouveau->fin              = NULL;
    nouveau->maximum          = lim;
    nouveau->size             = 0;
    return nouveau;
};


int anneau_list(Anneau* A, const char* message)
{
    if (A == NULL) return -1;
    if (message != NULL) printf("%s\n", message);
    if (A->maximum > 0)
    {
        printf("\n%d [of %d elements MAX]\n", 
               A->size, A->maximum);
    }
    else
    {
        printf("\n%d elements [MAX not defined]\n",
               A->size);
    }
    if (A->size < 1) return 0; // empty

    Noeud* p = A->debut;
    printf("\n    debut : %4d\n", A->debut->valeur );
    printf("    fin   : %4d\n", A->fin->valeur );
    printf("\nElements\n\n");
    int nc = 1;
    do
    {
        printf("%4d  ", p->valeur);
        p = p->suivant;
        if (nc == 10)
        {
            nc = 1;
            printf("\n");
        }
        else
            nc += 1;
    } while (p != NULL);
    printf("\nEnd\n");
    return 0;
};

/*
https://stackoverflow.com/questions/68566872/
is-there-a-way-to-automate-creation
-of-a-struct-within-a-struct
*/

如果您需要查看其他功能的示例实现,例如删除节点或删除整个列表的示例,请回信。