Relate structs in C

Asked

Viewed 359 times

1

Hello, I have to do the relation between structs in a work in C. I have a player struct with the name and code fields and an animal struct that has the name and code fields. I can normally insert players and animals into their struct.

struct jogador{
   int codigo;
   char nome;
}TJogador;

struct animal{
   int codigo;
   char nome;
}TAnimal;

However, each player can have several animals and need to relate these two structs so that when a player has an animal that is already inserted in the animal structure he only refers to this animal so when I list the players already list his animals.

Someone can give me a light?

  • 1

    Have you learned lists? You can make a *Tanimal list and put this list in your Tjogador struct. Posting the rest of the code makes it easier to implement and will improve the question. If you haven’t learned lists you can still use an array instead, if allowed in your problem.

2 answers

3


Do with chained or vector list. Example:

    struct animal{
       int codigo;
       char nome[200];
    }TAnimal;

    struct jogador{
       int codigo;
       char nome[200];
       // o numero de animais
       int numeroDeAnimais;
       // as referencias aos animais cadastrados.
       TAnimal* animal[200];
    }TJogador;

You must initialize the field numeroDeAnimais with the value 0 and when adding an animal, you should increase the value of the field numeroDeAnimais and add the animal at the end of the vector animal.

  • How do I add the animal to the player? For example: player[0]. code = 123; player[0]. name = 'Fulan'; player[0]. animal = ????

  • You can do as follows: player[0]. code = 0; player[0]. name = "So-and-so"; if(player[0].numberNUMERO_MAXIMO_DE_ANIMAIS) player[0]. animal[player[0]. numeroDeAnimais++] = &animal[0]; .

  • Perfect, I’ll try and come back!!!

  • It worked! Thank you!

2

There are some possibilities for relational C structures.

For a more "strong" reference, create a fixed size vector of animals in the player structure:

typedef struct animal {
   int codigo;
   char nome;
} TAnimal;

#define MAX_ANIMAIS 2
typedef struct jogador{
  int codigo;
  char nome;
  TAnimal animais[MAX_ANIMAIS];
} TJogador;

You can add animals to each player with:

TJogador jogador;
jogador.animais[0].codigo = 1;
jogador.animais[0].nome = 'a';
jogador.animais[1].codigo = 2;
jogador.animais[1].nome = 'b';
// ...
int i;
for (i = 0; i < MAX_ANIMAIS; i++) {
  printf("TAnimal{%d %c}\n", jogador.animais[i].codigo,
          jogador.animais[i].nome);
}

In this way, every player has a fixed number of animals (2 in the example) and the animal data will be part of the player structure.

Advantages: the code is simpler and the layout of the memory is ideal if the animals are accessed whenever the player is accessed. Disadvantages: less flexible, every player must have a fixed number of animals. This can be circumvented by creating a special instance of animal that represents the absence of the animal (for example, with id == -1).

Another possibility of a "weaker" relation is to make use of pointers. For example:

typedef struct animal {
   int codigo;
   char nome;
} TAnimal;

typedef struct jogador {
  int codigo;
  char nome;
  int num_animais;
  TAnimal* animais;
} TJogador;

Animals can be accessed with:

TJogador criaJogador(int codigo, char nome, int num_animais) {
  TJogador jogador;
  jogador.codigo = codigo;
  jogador.nome = nome;
  jogador.num_animais = num_animais;
  jogador.animais = (TAnimal*)malloc(sizeof(TAnimal) * num_animais);
  return jogador;
}

TJogador destroiJogador(TJogador* jogador) {
  free((*jogador).animais);
  (*jogador).num_animais = 0;
}

int main(int argc, char* argv[]) {
    TJogador jogador = criaJogador(1, 'a', 2);
    jogador.animais[0].codigo = 1;
    jogador.animais[0].nome = 'a';
    jogador.animais[1].codigo = 2;
    jogador.animais[1].nome = 'b';
    // ...
    int i;
    for (i = 0; i < jogador.num_animais; i++) {
       printf("TAnimal{%d %c}\n", jogador.animais[i].codigo,
              jogador.animais[i].nome);
    }
    destroiJogador(&jogador);
}

In this way, every player has a variable number of animals and the animal data will be dynamically allocated in memory.

Disadvantages: more complex code. Advantages: flexibility, making it possible for each player to have their own number of animals.

  • Your answer was great. But help me understand. What I need is for example the complete list of animals. When a player has a list animal I have to make reference to that animal on the list of animals and not add the animal directly on player, understand? Your "weak" example fits my solution?

  • If you need to refer to animals already allocated it would be better to keep pointers for them. The number of pointers can be fixed (TAnimal* animais[MAX_ANIMAIS]) or variable (TAnimal** animais) as examples. The assignment would be something like jogador.animais[i] = &lista_de_animais[j];.

  • I’ll take a test and come back!!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.