Struct help. Assigning a card struct to an array o

2019-03-04 20:06发布

问题:

These are my two structs:

typedef struct _card {
    int suit;
    int value;
} card;

typedef struct _deck {
    int num_cards;
    card *cards;
} deck;

This is my make a card function:

card *make_card(int suit, int value)
{
  card *newCard = malloc(sizeof(card));
  newCard->suit = suit;
  newCard->value = value;

  return newCard;
}

Now is where I am a bit stuck. I have to make a deck of cards. I know how to assign each value to the card, but I am stumped on how to allocate it in memory. I know it has to do with an array of cards in the deck struct but i cant figure out how.

deck *make_standard_deck()
{
  for (int i = 0; i <= 3; i++)
  {
    for (int j = 1; j <= 13; j++)
    {
      deck.cards[i] = make_card(int suit, int value);
    }
  }
}

回答1:

You should allocate the whole array of cards first then assign the individual cards later. Alt. you could also use realloc to make the array increasingly longer but that seems unnecessary here.

first change make_card (and maybe rename it)

card *init_card(card* newCard, int suit, int value)
{
  newCard->suit = suit;
  newCard->value = value;
  return newCard;
}

then change make_standard_deck

deck *make_standard_deck()
{
  const int numberOfValues = 13; // use constants when you can
  const int numberOfSuits = 4;

  deck* d = malloc(sizeof(deck)); // normally check return value
  d->num_cards = numberOfValues*numberOfSuits;
  d->cards = malloc(sizeof(card) * (d->num_cards));

  for (int i = 0; i < numberOfSuits; i++)
  {
    for (int j = 0; j < numberOfValues; j++)
    {
      // pass the card to initialized to the function
      // same as &(d->cards[i])
      init_card(d->cards + i, i + 1, j + 1);
    }
  }
  return d;
}

when you free it

void freeDeck( deck *d )
{
  if ( d != NULL )
  {
    free( d->cards );
  }
  free( d );
}


回答2:

To create a deck, first allocate memory for the deck structure, and then (assuming that you want an array of pointers to cards) allocate memory for the pointer array. Here's an example that creates a standard deck of 52 cards.

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

typedef struct _card {
    int suit;
    int value;
} card;

typedef struct _deck {
    int num_cards;
    card **cards;
} deck;

card *make_card(int suit, int value)
{
    card *newCard = malloc(sizeof(card));
    newCard->suit = suit;
    newCard->value = value;

    return newCard;
}

deck *make_standard_deck( void )
{
    deck *newDeck = malloc( sizeof(deck) );

    newDeck->num_cards = 52;
    newDeck->cards = malloc( 52 * sizeof(card *) );

    int index = 0;
    for ( int suit = 0; suit < 4; suit++ )
        for ( int value = 1; value <= 13; value++ )
            newDeck->cards[index++] = make_card( suit, value );

    return newDeck;
}

int main( void )
{
    int i;

    deck *stdDeck = make_standard_deck();

    for ( i = 0; i < stdDeck->num_cards; i++ )
        printf( "suit=%d value=%2d\n", stdDeck->cards[i]->suit, stdDeck->cards[i]->value );

    /* free the deck when we're done with it */
    for ( i = 0; i < stdDeck->num_cards; i++ )
        free( stdDeck->cards[i] );
    free( stdDeck->cards );
    free( stdDeck );
}


回答3:

If you know before hand the number of cards in the deck (say 52) then you can do it this way:

deck deck_cards[4][13];

for (int i = 0; i < 4; i++)
    {
            for (int j = 0; j < 13; j++)
            {
               deck_cards[i][j].cards = make_card(suit, value);
            }
     }


回答4:

I'd do something like this

struct Card
{
    int suit;
    int value;
};

struct Deck
{
    int num_cards;
    Card *cards;
};

//instead of returning a pointer simply return a Card struct
Card make_card(int suit, int value)
{
    Card newCard;
    newCard.suit = suit;
    newCard.value = value;

    return newCard;
}

Deck *deck = (Deck*) malloc(sizeof(Deck));
//So here's the part you're struggling with? Simply malloc num_cards of Card structs.
deck->cards = (Card*) malloc(sizeof(Card) * deck->num_cards);

//Now iterate through each Card struct in the deck
for(int i etc......)
    deck->cards[i] = make_card(suit, value); //make_card returns Card struct

So the deck holds a pointer to an array of cards based off of the decks num_cards value. Of course make sure to actually set num_cards beforehand unlike this example.