Ponteiro para Struct na linguagem C

Olá meus caros!

Estou desenvolvendo um jogo de cartas em linguagem C para implementar uma IA.

Define-se um tipo de dado como segue abaixo:

struct Estado
{
    /* Salva o estado anterior do jogo  */
    char stateGame[9];
    /* Salva o pr�ximo estado do jogo ap�s executar uma a��o*/
    char stateNext[9];
};
 typedef struct Estado estado;

Após isso, seto um valor default para os elementos da struct do tipo Estado, invoco:
void start_StateGame(estado *s)
{

    for (int i = 0; i < 9; i++)
    {
        s->stateGame[i] = '0'; 
        
        s->stateNext[i] = '0';
        
    }
    
}

Pois bem, quando vou imprimir na tela os elementos: stateGame e stateNext, ocorre o seguinte problema:

Quando imprimo o elemento stateGame, ocorre a impressão tanto do espaço de memória da variável mais o valor alocado para stateNext, dá um total de 18 caracteres. Quando imprimo stateNext, não ocorre isso, já que é a última variável da struct, entao apenas os 9 caracteres são exibidos na tela. Percebo que o ponteiro que aponta para o tipo estado é o mesmo ponteiro que aponta pro elemento stateGame da struct do tipo estado, por isso a impressão está considerando os caracteres dos dois elementos: stateGame e stateNext - tipo char.

Considerando os tipos abaixo:
j1 -  tipo player
estadoplayer: *tipo Estado**

Imprimo usando essas funções básicas do C:
A impressão indesejada dos 19 caracteres de stateGame ocorrem deste modo:

       printf("%s - estado  j1 \n", &j1.estadoPlayer.stateGame);
       puts(j1.estadoPlayer.stateGame);

A impressão correta dos 9 caracteres salvos em **stateNext**, funcionam do mesmo modo:

 printf("%s - estado  j1 \n", &j1.estadoPlayer.stateNext);
  puts(j1.estadoPlayer.stateNext);

Como faço para contornar este problema da impressão do elemento stateGame da struct Estado?

Grato.

Como você está imprimindo, pode por o código?

Coloquei o código da impressão e expliquei melhor os tipos de dados.

Tire o “&” da seguinte linha :

 printf("%s - estado  j1 \n", &j1.estadoPlayer.stateGame);

Tirei. O resultado da impressão dos 18 caracteres ainda persiste.

Estranho cara, pois quando se coloca o “&” antes do nome de uma variável ao inves de retornar o seu valor é retornado o seu endereço de memoria. Por isso pedi pra você remover, mas se mesmo assim ta imprimindo errado não sei o que pode ser.
Quando você disse estadoplayer: *tipo Estado**
quer dizer que a variável ‘estadoplayer’ é um ponteiro pra ponteiro? não entendi muito bem!

Realmente estranho amigo. Essa variável que você citou não é ponteiro, é uma variável normal do tipo estado - que é uma struct - como já citei na primeira postagem.

Muito cuidado ao preencher strings manualmente em C, no seu caso:

char stateGame[9];

Por exemplo, não terá 9 caracteres (0-8), mas sim 8 (0-7) pois a ultima posição você deve informar o final da string…

for (int i = 0; i < 9 - 1; i++) {
    s->stateGame[i] = '0'; 
    s->stateNext[i] = '0';
}
s->stateGame[8] = '\0';
s->stateNext[8] = '\0';

Talvez por isso o C esteja se perdendo no printf…

E uma dica de boa prática, em números constantes como o 9 use sempre uma constante por exemplo:

#include...
#define TAM 9
....
char stateGame[TAM];
char stateNext[TAM];
...
for (int i = 0; i < TAM; i++) //TAM - 1 se quiser testar o que indiquei...

Assim se futuramente precisar aumentar ou diminuir o tamanho do estado, só precisa mudar no define, fora a leitura que melhora muito, boa sorte!

1 curtida

Realmente resolveu o problema! Esqueci deste pequeno grande detalhe do C.
Obrigado amigo e valeu pela dica! Estou inclusive lendo o Clean Code para aprimorar meus programas.

eu não entendi por que vc esta guardando um array de char de 9 posições e setando o valor default para “00000000” mas vc pode considerar usar strcpy ( definida no header string.h )

strcpy(s->stateGame, "00000000");
strcpy(s->stateNext, "00000000");
1 curtida

Obrigado pela dica! Estou desenvolvendo uma plataforma para aprendizado de máquina no jogo de cartas Uno. O objetivo é acadêmico mesmo do projeto, porém estou divertindo com a linguagem C. E quem sabe até espalhar a plataforma aos interessados em IA :slight_smile: Meu repositŕio: https://github.com/harmendani/UnoGame.

Fiquei com uma dúvida, quando passo a string “000000000” para strcpy ela faz o ponteiro apontar para um local de memória alocado localmente. Seria uma boa prática definir um valor global e constante, por exemplo:

#define default "000000000"
strcpy(s->stateGame, default);

Creio que assim garanto que o meu ponteiro apontará sempre para uma porção da memória conhecida. Estou certo?

Ola

Vc está confundindo algumas coisas

  1. strcpy vai copiar o conteúdo da string, então tanto faz a posição de memoria inicial
  2. usando #define vc criou uma macro. O pre-processador C vai substituir esse termo pelo texto “000000” literal. Não é uma variável global, os defines são como Search/Replace dentro do seu codigo fonte.
1 curtida

Obrigado pela explicação.