Compile with maximum warnings:
Code:
main.c||In function 'createDeck':|
main.c|88|warning: passing argument 1 of 'printCard' from incompatible pointer type|
main.c|25|note: expected 'CardPtr' but argument is of type 'struct Card **'|
||=== Build finished: 0 errors, 1 warnings ===|
Typedef'ing a pointer should be avoided in most cases (such as this one). It has no real benefit here, and serves only to cause confusion.
I'm not sure what you're trying to do with your "createDeck" function. You create an array of pointers, allocate memory to each element, and for some reason return 0 at the end. (Incidentally, you should be checking your malloc calls to ensure they've succeeded before attempting to access the memory.)
If you want your deck to be represented by an array of struct, there's no need to create an array of pointer to struct and allocate memory. Just create an array of struct. You can declare it in "main", pass it to the "createDeck" function, and load it with values as needed.
Also, each function should do one thing and do it well. "createDeck" should not be printing any cards.
Since your "printCard" function only expects it to print a single card, you should just pass a single struct (or a pointer to that specific struct) to it. Passing the entire array plus the target element value is not the best approach.
You've also created named constants for values (which is good), but you're not using them when you do your loops.
You don't need a global array of strings to print card values - if they're only to be printed in a single function, they can be local to that function.
The struct member "suit" doesn't need to be a character. It is perfectly acceptable, and often preferable, to separate data from it's representation. The underlying code doesn't care about Diamonds or Clubs. You can use numeric values to represent the suits, and use these to print the corresponding strings only when needed, which is basically when reporting this information to the user.
I've created a quick mock-up of your code with these changes implemented. It's not thoroughly tested, and a bit sloppy (since I tried to maintain your basic representations), but it should illustrate the points I've made.
Code:
// Mock-up modification of the OP's example
// Note: Minimal error-checking for purposes of illustration
#include <stdio.h>
#define DECK_SIZE 52
#define NFACES 13
#define NVALUES 13
enum suits_e
{
SUIT_CLUBS,
SUIT_DIAMONDS,
SUIT_SPADES,
SUIT_HEARTS,
NSUITS
};
typedef struct Card
{
int face;
int suit;
} Card;
void createDeck(Card *deck);
void printCard(Card *card);
int main(void)
{
Card deck[DECK_SIZE];
int i;
createDeck(deck);
for(i = 0; i < DECK_SIZE; i++)
printCard(&deck[i]);
return 0;
}
void createDeck(Card *deck)
{
int face, suit;
int i = 0;
for(suit = SUIT_CLUBS; suit < NSUITS; suit++)
{
for(face = 0; face < NFACES; face++)
{
deck[i].face = face;
deck[i].suit = suit;
++i;
}
}
}
void printCard(Card *card)
{
const char *face_str[NFACES] = {
"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"
};
const char *suit_str[NSUITS] = {
"Clubs", "Diamonds", "Spades", "Hearts"
};
printf("%s of %s\n", face_str[card->face], suit_str[card->suit]);
}
Any questions?