[英]C: accessing members of struct in a function
我試圖在我的函數print_shoe中使用結構成員'size',但我的for循環不運行。 但是,如果我用for循環中的int替換'c-> size',它運行就好了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DECK_SIZE 52
#define NUM_FACES 13
#define NUM_SUITS 4
#define LENGTH_FACES 6
#define LENGTH_SUITS 9
typedef struct cards {
char suits[NUM_SUITS][LENGTH_SUITS];
char faces[NUM_FACES][NUM_FACES];
int suit, face, card, value, size;
int *values[NUM_FACES];
} cards;
char buf[101];
void print_shoe();
void init_decks();
int rand_int();
void shuffle();
int main(void) {
srand( time(NULL) );
int decks_input = 0;
int numberOfDecks = 1;
do {
printf("\nEnter number of decks to be used in the game (1-8):\n\n");
if (fgets(buf, sizeof(buf), stdin) != NULL)
if (sscanf (buf, "%d", &decks_input))
numberOfDecks = decks_input;
} while (numberOfDecks < 1 || numberOfDecks > 8);
cards *shoe = malloc(sizeof(cards) * numberOfDecks * DECK_SIZE);
shoe->size = numberOfDecks * DECK_SIZE;
shuffle(shoe);
print_shoe(shoe);
free(shoe);
return 0;
}
void print_shoe(cards *c) {
int i;
for (i = 0; i < c->size; i++) {
printf("card #%d = %s of %s\n", i+1, c->faces[c[i].face], c->suits[c[i].suit]);
}
}
void init_decks(cards *c) {
int i;
for (i = 0; i < c->size; i++) {
c[i].card = i;
c[i].suit = c[i].card % NUM_SUITS;
c[i].face = c[i].card % NUM_FACES;
}
}
void shuffle(cards *c) {
init_decks(c);
int i, j;
cards tmp;
for (i = c->size - 1; i > 0 ; i--) {
j = rand_int(i + 1);
tmp = c[j];
c[j] = c[i];
c[i] = tmp;
}
}
int rand_int(int n) {
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
do {
rnd = rand();
} while (rnd >= limit);
return rnd % n;
}
編輯:問題已經廣泛更新,以回應需要進一步澄清的評論
在修訂后的代碼中,您有:
cards *shoe = malloc(sizeof(cards) * numberOfDecks * DECK_SIZE);
shoe->size = numberOfDecks * DECK_SIZE;
// You probably need init_decks(shoe); here!!!
shuffle(shoe);
print_shoe(shoe);
print_shoe()
代碼只是打印,但是你沒有初始化malloc()
以外的數據,所以你要打印垃圾。 malloc()
返回的數據未初始化,必須在讀取之前進行初始化。 我打字的時候問題發生了變化; 你還沒有打電話給init_decks(shoe);
如你所願。
這不是它不起作用的原因 - 我不確定現在的問題是什么 - 但它幾乎值得評論。 你有:
void shuffle(cards *c) {
init_decks(c);
int i, j;
cards tmp;
for (i = c->size - 1; i > 0 ; i--) {
j = rand_int(i + 1);
tmp = c[j];
c[j] = c[i];
c[i] = tmp;
}
}
如果您打算使用C99技術來聲明具有最小范圍的變量,那么您應該寫:
void shuffle(cards *c) {
init_decks(c);
for (int i = c->size - 1; i > 0; i--) {
int j = rand_int(i + 1);
cards tmp = c[j];
c[j] = c[i];
c[i] = tmp;
}
}
(我不會錯過對init_decks()
的調用, init_decks()
它是這樣編寫的。)
正如評論中所指出的,您的cards
結構相當重要。 您為每張卡分配足夠的空間來存儲它可能具有的等級和套裝。 這實際上沒有必要。
此代碼將Deck
與Card
分開。 它在Deck
結構中使用一個靈活的陣列成員來固定卡片,這很方便。 您可能更喜歡在那里使用常規指針,在這種情況下,您需要一對內存分配和一個函數deck_free()
來釋放由deck_alloc()
分配的內存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NUM_FACES 13
#define NUM_SUITS 4
#define DECK_SIZE (NUM_FACES * NUM_SUITS)
#define LENGTH_FACES 6
#define LENGTH_SUITS 9
static const char suits[NUM_SUITS][LENGTH_SUITS] =
{
"Clubs",
"Diamonds",
"Hearts",
"Spades"
};
static const char faces[NUM_FACES][NUM_FACES] =
{
"Ace",
"Deuce",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Jack",
"Queen",
"King",
};
typedef struct Card
{
int suit;
int face;
int card;
} Card;
typedef struct Deck
{
int size;
Card cards[]; // Flexible array member
} Deck;
void print_shoe(const Deck *d);
void init_decks(Deck *d);
int rand_int(int n);
void shuffle(Deck *d);
static Deck *deck_alloc(int numberOfDecks);
int main(void)
{
srand( time(NULL) );
int numberOfDecks = 1;
do
{
char buf[101];
printf("\nEnter number of decks to be used in the game (1-8):\n\n");
if (fgets(buf, sizeof(buf), stdin) != NULL)
{
int decks_input;
if (sscanf (buf, "%d", &decks_input))
numberOfDecks = decks_input;
}
} while (numberOfDecks < 1 || numberOfDecks > 8);
Deck *shoe = deck_alloc(numberOfDecks);
shuffle(shoe);
print_shoe(shoe);
free(shoe);
return 0;
}
static Deck *deck_alloc(int numberOfDecks)
{
Deck *shoe = malloc(sizeof(Deck) + (sizeof(Card) * numberOfDecks * DECK_SIZE));
if (shoe == 0)
{
fprintf(stderr, "out of memory\n");
exit(1);
}
shoe->size = numberOfDecks * DECK_SIZE;
return shoe;
}
void print_shoe(const Deck *d)
{
for (int i = 0; i < d->size; i++)
printf("card #%d = %s of %s\n", i+1, faces[d->cards[i].face], suits[d->cards[i].suit]);
}
void init_decks(Deck *d)
{
for (int i = 0; i < d->size; i++)
{
d->cards[i].card = i;
d->cards[i].suit = d->cards[i].card % NUM_SUITS;
d->cards[i].face = d->cards[i].card % NUM_FACES;
}
}
void shuffle(Deck *d)
{
init_decks(d);
for (int i = d->size - 1; i > 0 ; i--)
{
int j = rand_int(i + 1);
Card tmp = d->cards[j];
d->cards[j] = d->cards[i];
d->cards[i] = tmp;
}
}
int rand_int(int n)
{
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
do
{
rnd = rand();
} while (rnd >= limit);
return rnd % n;
}
樣本輸出:
$ ./cards
Enter number of decks to be used in the game (1-8):
1
card #1 = Eight of Clubs
card #2 = Jack of Clubs
card #3 = Deuce of Diamonds
card #4 = Jack of Hearts
card #5 = Queen of Clubs
card #6 = Four of Hearts
card #7 = Six of Spades
card #8 = King of Hearts
card #9 = Five of Spades
card #10 = King of Clubs
card #11 = Deuce of Clubs
card #12 = King of Spades
card #13 = Four of Spades
card #14 = Nine of Diamonds
card #15 = Five of Hearts
card #16 = Deuce of Spades
card #17 = Ten of Clubs
card #18 = Five of Diamonds
card #19 = Ten of Spades
card #20 = Three of Spades
card #21 = Nine of Hearts
card #22 = Six of Clubs
card #23 = Ace of Clubs
card #24 = Three of Clubs
card #25 = Queen of Hearts
card #26 = Jack of Diamonds
card #27 = Nine of Clubs
card #28 = Four of Clubs
card #29 = Seven of Spades
card #30 = Ace of Diamonds
card #31 = Six of Diamonds
card #32 = Three of Hearts
card #33 = Queen of Diamonds
card #34 = Ten of Hearts
card #35 = Ten of Diamonds
card #36 = Seven of Diamonds
card #37 = Seven of Clubs
card #38 = Deuce of Hearts
card #39 = Ace of Hearts
card #40 = Jack of Spades
card #41 = Eight of Diamonds
card #42 = Eight of Spades
card #43 = Ace of Spades
card #44 = Three of Diamonds
card #45 = Queen of Spades
card #46 = Five of Clubs
card #47 = Four of Diamonds
card #48 = King of Diamonds
card #49 = Nine of Spades
card #50 = Eight of Hearts
card #51 = Six of Hearts
card #52 = Seven of Hearts
$
直接解決這個問題並忽略了這種方法的智慧,你的問題如下(Raymond Chen也提到過)。
cards *shoe = malloc(sizeof(cards) * numberOfDecks * DECK_SIZE);
上面的一(numberOfDecks * DECK_SIZE)
鞋子指向足夠的內存來存儲(numberOfDecks * DECK_SIZE)
struct cards
。 結構,因而有成員,在這一點上都是單元化的,這意味着shoe[i].size
可以是任何比特序列。
shoe-> size = numberOfDecks * DECK_SIZE;
此行僅查看第一個 struct cards
並將其size
設置為(numberOfDecks * DECK_SIZE)
。 其余struct cards
的size
成員仍然是單元化的。
在shuffle
,您對init_decks
的調用初始化card
, suit
和face
但不是size
。 當您稍后洗牌時,具有單元size
成員的卡很有可能成為第一名。
因此,根據您當前的方法,如果將此行添加到init_decks
,以下內容應該會得到您想要的init_decks
。
void init_decks(cards *c) {
int i;
int size = c->size;
for (i = 0; i < c->size; i++) {
c[i].size = size;
c[i].card = i;
c[i].suit = c[i].card % NUM_SUITS;
c[i].face = c[i].card % NUM_FACES;
}
}
您已聲明指針但尚未將其初始化為指向的有效內存位置。
ex *ex_p = malloc(sizeof(ex));
ex_p->size = 10;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.