1
votes

stocker différentes structures dans un tableau

J'ai essayé de créer un tableau qui stocke différentes structures et je n'ai pas réussi à le faire. Est-il possible de stocker différentes structures dans un seul tableau? sinon, y a-t-il une structure de données de dictionnaire en C?

Voici ce que j'ai:

struct A {
    int row;
    int col;
};
struct B {
    int row;
    int col;
};

struct A bishop;
struct B rook;

bishop.row = 1;
bishop.col = 1;
rook.row = 2;
rook.col = 2;

arr[2] = {bishop,rook};

de quel type de données ai-je besoin pour donner le tableau? p >


20 commentaires

les membres du tableau flexible sont aussi proches que vous obtenez en C.


Comment et où ces structures existent-elles? Si c'est global ou alloué, utilisez simplement un tableau de pointeurs ... Vous auriez une structure de base quelque chose comme struct {void * pData, enum eSomeType id; } puis lorsque vous avez un tableau de ces éléments où le pData pointe vers votre structure et l'id décrit le type.


Non, en gros, vous ne pouvez pas. Tous les éléments du tableau doivent être du même type . Si vous pouvez stocker des pointeurs ou un niveau supérieur union ( union manystruct {struct s1 s1; struct s2 s2;. ..; struct sN sN;}; ), cela peut être possible.


"Est-il possible de stocker différentes structures dans un seul tableau?" - Oui, en utilisant des pointeurs ou des unions.


Que signifie différentes structures ? Différents types? Dans ce cas, pensez à utiliser une union, si vous n'aimez pas la suggestion de @SPlatten.


Oui, vous pouvez. Mais vous avez besoin de quelque chose pour les distinguer.


@ryyker a ajouté du code, regardez


@DarkLeader, pourquoi avez-vous même deux structures? Vous ne pouvez en utiliser qu'un seul car les champs sont identiques


@ Youssef13 Je fais une partie d'échecs, chaque pièce a un modèle de mouvement différent, je n'ai pas ajouté tous les attributs


@DarkLeader, Pourtant, vous ne pouvez créer qu'une seule structure. et ajoutez un champ d'énumération par exemple pour déterminer le type de pièce.


@ Youssef13 qu'en est-il du mouvement de la pièce? comment cela fonctionnera-t-il?


Une structure n'a rien à voir avec le comportement des pièces. Il ne contient que l ' état . Vous devez gérer le mouvement dans une fonction, que ce soit dans la fonction principale ou dans une autre fonction. La structure aura un champ d'énumération pour déterminer de quelle pièce il s'agit pour aider votre fonction à déterminer le mouvement.


@ Youssef13 ne sont pas fondamentalement de mauvaises classes? J'ai pensé que je pourrais ajouter directement les attributs dont j'ai besoin


Les structures ne contiennent que des champs, pas des méthodes. Vous ne pouvez pas avoir de fonction à l'intérieur de votre structure. Vous devez donc ajouter un champ pour déterminer le type de pièce et valider les déplacements en fonction de la valeur de ce champ.


@ Youssef13 merci, merci à tous.


Les structures @DarkLeader sont TRES mauvaises classes. En général, n'essayez pas d'imiter la POO en C. Si vous avez vraiment besoin de la POO, choisissez une autre langue.


@klutt et si je suis coincé avec C pour l'instant ..?


@DarkLeader Il n'y a aucun problème qui nécessite la POO. ;)


@klutt bien sûr mais ce sera un cauchemar de créer des choses sans oop


@DarkLeader C'est souvent un cauchemar encore plus grand d'essayer d'imiter oop dans une langue qui ne le prend pas en charge. Utiliser des pointeurs ou des unions pour cela est une option, mais c'est souvent le signe qu'il serait sage de repenser complètement ce que vous faites.


4 Réponses :


0
votes

Vous pouvez soit utiliser un tableau de pointeurs vides puis interpréter ce vers quoi il pointe, soit utiliser une union de structures, par exemple:

struct Master {
    int whatisthis;
    union {
        struct {
            int i;
            //...
        } s1;
        struct {
            char *s;
            //...
        } s2;
    } u;
} x;

le int whatisthis peut contenir par exemple un 0 ou un 1 pour indiquer que l'union contient s1 ou s2.


0 commentaires

1
votes

La dernière modification de votre message d'origine clarifie les choses. Vous vous demandez vraiment si un tableau de frappé est possible. (pas un tableau de différents struct .)

Oui, ce que vous avez décrit dans votre édition peut être accompli de plusieurs manières. La méthode suivante utilise simplement un typedef avec enum et inclut quelques améliorations de dénomination possibles:

 white[BISHOP].row = 3;
 white[BISHOP].col = 2;

Vous avez maintenant 2 tableaux de 16 instances, pièces d'échecs NOIR et BLANC, chaque instance peut contenir des valeurs différentes, mais sont identiques dans tous les autres cas.

Vous pouvez maintenant utiliser une énumération pour aider à délimiter chaque membre du tableau:

enum {
   KING,
   QUEEN,
   BISHOP,
   KNIGHT,
   ROOK,
   PAWN
};

appelable comme suit:

typedef struct {
    int row;
    int col;
}BLACK, WHITE;


BLACK black[16];
WHITE white[16];


0 commentaires

4
votes

Les tableaux contiennent des structures de données du même type. Vous ne pouvez donc pas mettre deux structures différentes dans un tableau.

Ce que vous pouvez faire est de créer une autre structure contenant les deux autres:

enum piece_type {
     PAWN,
     KNIGHT,
     BISHOP,
     ROOK,
     QUEEN,
     KING
};

struct piece {
    enum piece_type type;
    int row;
    int col;
};

...

struct piece bishop = { BISHOP, 1, 1 };
struct piece rook = { ROOK, 2, 2 };

struct piece arr[2] = {bishop,rook};

Ce que je vous soupçonne en fait besoin est une structure commune qui peut modéliser toutes les pièces comme ceci:

struct A_B {
    struct A a;
    struct B b;
};

...

struct A_B ab = { bishop, rook };

De cette façon, vous avez un champ enum qui vous indique le type de la pièce pour vous permettre de l'utiliser comme il convient.


7 commentaires

J'obtiens toujours "erreur: une étiquette ne peut faire partie d'une déclaration et une déclaration n'est pas une déclaration" quand je crée un morceau comme vous l'avez écrit "struct piece bishop = {BISHOP, 1, 1};". une idée pourquoi? ou une solution?


@DarkLeader Vous avez mal saisi quelque chose. Très probablement un deux-points (: ) qui vient normalement après une étiquette.


case 'k': struct piece blackKing = {ROI, i, j,}; pièces [index] = blackKing;


J'ajoute les structures à un tableau appelé pieces. et ceci est dans un bloc de boîtier de commutation


@DarkLeader Vous ne pouvez pas déclarer une variable juste avant une étiquette de cas. Vous devrez soit créer une nouvelle portée de bloc, soit déplacer la variable au-dessus du commutateur .


J'ai besoin d'utiliser un boîtier de commutation ou beaucoup d'instructions if. es-tu sûr que je ne peux pas changer de cas?


@DarkLeader Vous pouvez utiliser un commutateur , vous ne pouvez simplement pas déclarer une variable immédiatement après une étiquette de cas. Vous devez soit le déplacer, soit créer un nouveau bloc avec { et } .



0
votes

Hormis le refactor proposé par @dbush (que je pense que c'est le bon chemin à suivre), je suis surpris que personne n'ait proposé une solution utilisant les union s.

struct A {
    int row;
    int col;
};
struct B {
    int row;
    int col;
};
enum types_t {
    TYPE_A = 0,
    TYPE_B = 1
};
union possible_values_t {
    struct A a;
    struct B b;
};
struct array_t {
    enum types_t t;
    union possible_values_t value;
};

struct array_t arr[2] = {{TYPE_A, {0,0}}, {TYPE_B, {5,4}}};


0 commentaires