C:访问函数中的struct成员

C:访问函数中的struct成员,c,struct,C,Struct,我试图在函数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 L

我试图在函数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;
}
#包括
#包括
#包括
#定义甲板尺寸52
#定义NUM_面13
#定义NUM_4
#定义面6的长度
#定义长度为9
typedef结构卡{
char套装[数量套装][长度套装];
字符面[NUM_faces][NUM_faces];
int套装、正面、卡片、价值、尺寸;
int*值[NUM_FACES];
}卡片;
char-buf[101];
作废印花鞋();
void init_decks();
int rand_int();
无效洗牌();
内部主(空){
srand(时间(空));
int\u输入=0;
int numberofdeck=1;
做{
printf(“\n输入游戏中使用的牌组数(1-8):\n\n”);
如果(fgets(buf,sizeof(buf),stdin)!=NULL)
if(sscanf(buf、%d、&U输入))
numberOfDecks=甲板\输入;
}而(甲板数量<1 | |甲板数量>8);
卡片*shoe=malloc(卡片尺寸)*卡片数量*卡片尺寸);
鞋->尺寸=甲板数量*甲板尺寸;
洗牌(鞋);
印花鞋;
免费(鞋);
返回0;
}
无效打印鞋(卡片*c){
int i;
对于(i=0;isize;i++){
printf(“卡#%d=%s of%s\n”,i+1,c->faces[c[i].face],c->suits[c[i].suit]);
}
}
无效初始甲板(卡片*c){
int i;
对于(i=0;isize;i++){
c[i].card=i;
c[i].suit=c[i]。卡%NUM\u suts;
c[i]。面=c[i]。卡片%NUM\u面;
}  
}
无效洗牌(牌*c){
初始甲板(c);
int i,j;
卡片tmp;
对于(i=c->size-1;i>0;i--){
j=rand_int(i+1);
tmp=c[j];
c[j]=c[i];
c[i]=tmp;
}
}
整数和整数(整数n){
int limit=RAND_MAX-RAND_MAX%n;
int rnd;
做{
rnd=rand();
}而(rnd>=限制);
返回rnd%n;
}

编辑:问题已被广泛更新,以响应需要进一步澄清的评论

您已声明了一个指针,但尚未将其初始化为要指向的有效内存位置

 ex *ex_p = malloc(sizeof(ex));
 ex_p->size = 10;

在修订后的代码中,您有:

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\u 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()
的调用了。)


正如在一篇评论中所指出的,你的
卡片
结构相当繁重。你(为每张牌)分配足够的空间来存储它可能拥有的等级和西装。这真的没有必要

此代码将
卡片组
卡片
分开。它在
结构中使用一个灵活的阵列成员来容纳卡,这很方便。您可能更喜欢在那里使用常规指针,在这种情况下,您需要一对内存分配和一个函数
deck\u free()
来释放
deck\u alloc()分配的内存


直接解决问题,忽略这种方法的智慧,你的问题如下(陈雷蒙也提到)

上面的行表示shoe指向足够的内存来存储
(numberOfDecks*DECK_SIZE)
结构卡
。结构和这些成员在这一点上都是统一的,这意味着
shoe[i]。大小可以是任何位序列

鞋->尺寸=甲板数量*甲板尺寸

这一行只查看第一张
结构卡
,并将其
大小设置为
(NumberOfDeck*DECK_size)
。其余的
结构卡
大小
成员仍保持单元化

shuffle
中,您对
init_decks
的调用将初始化
套装
,和
,但不初始化
大小
。当你稍后洗牌时,具有单位化
大小
成员的牌很有可能成为第一名

因此,在您当前的方法下,如果您将这一行添加到
init\u deck
,下面的内容应该会得到您想要的

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;
       }  
}
void init_组(卡片*c){
int i;
int size=c->size;
对于(i=0;isize;i++){
c[i].尺寸=尺寸;
c[i].card=i;
c[i].suit=c[i]。卡%NUM\u suts;
c[i]。面=c[i]。卡片%NUM\u面;
}  
}

不幸的是,我在代码中做到了这一点。。你还能发现什么吗?这就好像循环根本就没有运行。。但也没有给我任何错误。如果我简单地将for循环中的'ptr->size'与值'10'交换,结果会很好。如果您只有一个实例,那么就没有迭代或使用for循环的意义。你能发布你完整的实际代码吗?你的代码不能编译。1.将
print\u shoe
放在
main
2之前<代码>(卡片*)malloc(…)
。换了这些之后,我的机器运行得很好。@gongzhitaao:演员阵容是不必要的,是个坏主意。只需确保您拥有
#include
,从
void*
cards*
的转换将隐式完成。您没有定义
buf
DECK_SIZE
,并且您缺少
所需的
include
指令。你说你的函数“不能访问”结构成员。这是什么意思?当你尝试时会发生什么?您是否收到编译时错误消息?如果是的话,给我们看看。向我们展示一张显示问题的卡片,并告诉我们问题是什么。
printf(“卡片
$ ./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
$
  cards *shoe = malloc(sizeof(cards) * numberOfDecks * DECK_SIZE);
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;
       }  
}