【问题标题】:Add value of playing cards - with pointers and structures增加扑克牌的价值 - 带有指针和结构
【发布时间】:2017-04-02 06:27:16
【问题描述】:

我正在处理一些 c 编程问题,目前我遇到了一个与指针相关的问题

问:编写一个函数,将两张牌二十一点 HAND 的值作为输入,并返回该手牌的总点数。价值 牌'2'到'9'的牌面值相等,牌'T','K','Q','J'值10分,A牌('A')值11分 除非它带有另一个 A,否则第二个 A 值 1 分。该程序应该能够捕获错误的输入。

示例: 输入卡片:A Q 分数是21

输入卡片:A A 分数是12

我之前已经解决过这个问题,但这次我必须使用我仍然相当陌生的指针。获取卡值和计算卡必须在一个函数中完成。到目前为止,这是我所拥有的:

#include <stdio.h>
#define HAND 2
struct player_hand
{
     char card1;
     char card2;
};


void getHandValue(struct player_hand * hnd_ptr, char size, char size2)
{
    int first_card;
    int second_card;

    //get cards from user
    scanf("%c %c",&hnd_ptr->card1, &hnd_ptr->card2);
    printf("Enter Cards: %c %c", &hnd_ptr->card1, &hnd_ptr->card2);

    //check value of first card in hand 
    if(hnd_ptr->card1<='9' && hnd_ptr->card1>='2')
    {
        first_card=(int)hnd_ptr->card1 -48;

    }
    //check for special cards: king, queen, jack, ten
    else if(hnd_ptr->card1=='T'||hnd_ptr->card1=='K'||hnd_ptr->card1=='Q'||hnd_ptr->card1=='J')
    {
        first_card=10;
    }
    //if first card is Ace
    else if(hnd_ptr->card1=='A')
    {
        first_card=11;
    }
    else
    {
        //card not valid
        printf("Not a valid card: %c",hnd_ptr->card1);
        return;
    }

    //check value of 2nd card
    if(hnd_ptr->card2<='9' && hnd_ptr->card2>='2')
    {
        second_card=(int)hnd_ptr->card2 -48;

    }
    //if 2nd card is a special kind
    else if(hnd_ptr->card2=='T'||hnd_ptr->card2=='K'||hnd_ptr->card2=='Q'||hnd_ptr->card2=='J')
    {
        second_card=10;
    }
    //if 2nd card is Ace
    else if(hnd_ptr->card2=='A')
    {
        if(hnd_ptr->card1=='A')
        second_card=1;
        else
        second_card=11;
    }
    else
    {
        //if 2nd card not valid
        printf("Not a valid card: %c",hnd_ptr->card2);
        return;
    }

    add cards
    printf("\nThe total card value is: %d",first_card+second_card);

}

//call function, test if works
//calling it wrong?
int main(void) 
{
    struct player_hand hnd [HAND]  =  { {'A', 'A'}};
    getHandValue (hnd, HAND);
    return;
}

【问题讨论】:

  • 你现在到底面临什么问题?
  • 如果您将指针传递给结构,则无需为手做参数。您可以使用指针访问它们。

标签: c


【解决方案1】:

你有一些错误。

main 调用不正确。

该函数不需要大小参数,如果需要,它们应该是int

来自main的错误return

函数中printf是错误的。

事情比他们需要的复杂得多,因为struct 使用两个标量而不是数组。

我已经创建了您的程序的两个版本。一个带有错误注释的。还有一个可以清理东西。

这是带注释的版本:

#include <stdio.h>

#define HAND 2

struct player_hand {
    char card1;
    char card2;
};

// NOTE/BUG: use 'int' for size and size2
void
getHandValue(struct player_hand *hnd_ptr, char size, char size2)
{
    int first_card;
    int second_card;

    // get cards from user
    scanf("%c %c", &hnd_ptr->card1, &hnd_ptr->card2);

// NOTE/BUG: this would print the _address_ of the values vs. the values
    printf("Enter Cards: %c %c", &hnd_ptr->card1, &hnd_ptr->card2);

// NOTE/BUG [sort of]: the code below is cut-n-paste replication because you
// have separate card1 and card2 in the struct -- this "cries out" for an
// array and a loop. Consider the general case where you have 5 cards in the
// hand (e.g. five card charlie). The code would be easier even with an array
// of only two

    // check value of first card in hand
    if (hnd_ptr->card1 <= '9' && hnd_ptr->card1 >= '2') {
        first_card = (int) hnd_ptr->card1 - 48;

    }
    // check for special cards: king, queen, jack, ten
    else if (hnd_ptr->card1 == 'T' || hnd_ptr->card1 == 'K' || hnd_ptr->card1 == 'Q' || hnd_ptr->card1 == 'J') {
        first_card = 10;
    }
    // if first card is Ace
    else if (hnd_ptr->card1 == 'A') {
        first_card = 11;
    }
    else {
        // card not valid
        printf("Not a valid card: %c", hnd_ptr->card1);
        return;
    }

    // check value of 2nd card
    if (hnd_ptr->card2 <= '9' && hnd_ptr->card2 >= '2') {
        second_card = (int) hnd_ptr->card2 - 48;

    }
    // if 2nd card is a special kind
    else if (hnd_ptr->card2 == 'T' || hnd_ptr->card2 == 'K' || hnd_ptr->card2 == 'Q' || hnd_ptr->card2 == 'J') {
        second_card = 10;
    }
    // if 2nd card is Ace
    else if (hnd_ptr->card2 == 'A') {
        if (hnd_ptr->card1 == 'A')
            second_card = 1;
        else
            second_card = 11;
    }
    else {
        // if 2nd card not valid
        printf("Not a valid card: %c", hnd_ptr->card2);
        return;
    }

    printf("\nThe total card value is: %d", first_card + second_card);
}

//call function, test if works
//calling it wrong?
int
main(void)
{

// NOTE: based on usage, this is only an array because you're not using &hnd
// below
    struct player_hand hnd[HAND] = {
        {'A', 'A'}
    };

// NOTE/BUG: too few arguments to function, but why pass count at all?
    getHandValue(hnd, HAND);

// NOTE/BUG: need to return value (e.g. return 0)
    return;
}

这是清理后的版本:

#include <stdio.h>

#define CARDS_PER_HAND      2

struct player_hand {
    char card[CARDS_PER_HAND];
};

void
getHandValue(struct player_hand *hnd_ptr)
{
    int idx;
    int card;
    int sum;
    int count[CARDS_PER_HAND];

    // get cards from user
    printf("Enter Cards:");
    fflush(stdout);
    for (idx = 0;  idx < CARDS_PER_HAND;  ++idx)
        scanf(" %c", &hnd_ptr->card[idx]);

    // print cards
    printf("Cards entered:");
    for (idx = 0;  idx < CARDS_PER_HAND;  ++idx)
        printf(" %c", hnd_ptr->card[idx]);
    printf("\n");

    for (idx = 0;  idx < CARDS_PER_HAND;  ++idx) {
        card = hnd_ptr->card[idx];

        // simple cards
        if (card <= '9' && card >= '2') {
            count[idx] = (card - '2') + 2;
            continue;
        }

        switch (card) {
        case 'A':
            count[idx] = 11;
            if ((idx == 1) && (count[0] == 11))
                count[idx] = 1;
            break;

        case 'T':
        case 'K':
        case 'Q':
        case 'J':
            count[idx] = 10;
            break;

        default:
            printf("Not a valid card: %c", card);
            return;
            break;
        }
    }

    sum = 0;
    for (idx = 0;  idx < CARDS_PER_HAND;  ++idx)
        sum += count[idx];

    printf("The total card value is: %d\n", sum);
}

int
main(void)
{
    struct player_hand hnd;

    getHandValue(&hnd);

    return 0;
}

【讨论】:

  • 天哪,谢谢!我会查看你的代码并研究它。真的很想掌握指针,但有点难。
  • 不客气!我猜的关键点是,每当似乎有很多重复的措辞(即通过card = hnd_ptr-&gt;card[idx] 简化,它允许在循环的其余部分使用更简单的card)或代码重复[有为每张卡单独拼出相同的代码],这表明应该重构架构。有了更多经验,您将能够在最初的编码过程中发现这些简化,但是,如果您发现自己“把自己画到一个角落”,就会停下来,喘口气,重新做事。
【解决方案2】:

您没有将hnd 的地址传递给函数getHandValue()。为此,您必须使用 & 运算符 getHandValue(&amp;hnd) 传递地址。

您也没有正确初始化struct player_hand hnd。一组{} 太多了。

【讨论】:

    【解决方案3】:

    这是您的 main() 代码的编辑版本,它只是对您的指针的设置方式进行了一些小的修改。

    // main
    int main(void) 
    {
        // minor edits to fix the code here
        struct player_hand hnd = {'A', 'A'};
        struct player_hand *hndPtr = &hnd;
    
        getHandValue (hndPtr);
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      如果除了其他答案之外,您的意图是传递一个 2-hand 数组,则您需要在评分函数的循环中处理双手。例如:

      #include <stdio.h>
      
      #define HAND 2
      
      struct player_hand
      {
          char card1;
          char card2;
      };
      
      void getHandValue (struct player_hand *hnd_ptr, int size)
      {
          int first_card;
          int second_card;
      
          /* get cards from user */
          for (int i = 0; i < size; i++) {
              printf ("\nenter cards for hand %d (card1 card2): ", i);
      
              /* you must handle the '\n' that remains after last char */
              if (scanf ("%c %c%*c", &hnd_ptr[i].card1,  &hnd_ptr[i].card2) != 2) {
                  fprintf (stderr, "error: invalid entry.\n");
                  return;
              }
              printf ("you entered: %c %c\n", hnd_ptr[i].card1, hnd_ptr[i].card2);
          }
      
          for (int i = 0; i < size; i++) 
          {
              /* check value of first card in hand */
              if(hnd_ptr[i].card1 <= '9' && hnd_ptr[i].card1 >= '2')
              {
                  first_card = (int)hnd_ptr[i].card1 - '0';
      
              }
              /* check for special cards: king, queen, jack, ten */
              else if (hnd_ptr[i].card1 == 'T' || hnd_ptr[i].card1 == 'K' || 
                      hnd_ptr[i].card1 == 'Q' || hnd_ptr[i].card1 == 'J')
              {
                  first_card = 10;
              }
              /* if first card is Ace */
              else if (hnd_ptr[i].card1 == 'A')
              {
                  first_card = 11;
              }
              else
              {
                  /* card not valid */
                  printf("Not a valid card: %c",hnd_ptr[i].card1);
                  return;
              }
      
              /* check value of 2nd card */
              if(hnd_ptr[i].card2 <= '9' && hnd_ptr[i].card2 >= '2')
              {
                  second_card=(int)hnd_ptr[i].card2 - '0';
      
              }
              /* if 2nd card is a special kind */
              else if (hnd_ptr[i].card2 == 'T' || hnd_ptr[i].card2 == 'K' || 
                      hnd_ptr[i].card2 == 'Q' || hnd_ptr[i].card2 == 'J')
              {
                  second_card = 10;
              }
              /* if 2nd card is Ace */
              else if (hnd_ptr[i].card2 == 'A')
              {
                  if (hnd_ptr[i].card1 == 'A')
                      second_card = 1;
                  else
                      second_card = 11;
              }
              else
              {
                  /* if 2nd card not valid */
                  printf ("Not a valid card: %c", hnd_ptr[i].card2);
                  return;
              }
      
              /* add cards */
              printf ("\nThe total cards value (hand %d) is: %d\n", 
                      i, first_card + second_card);
          }
      }
      
      int main(void) 
      {
          struct player_hand hnd[HAND]  =  { {'A', 'A'}, {'A', 'A'} };
          getHandValue (hnd, HAND);
      
          return 0;
      }
      

      使用/输出示例

      $ ./bin/cards
      
      enter cards for hand 0 (card1 card2): A A
      you entered: A A
      
      enter cards for hand 1 (card1 card2): 8 K
      you entered: 8 K
      
      The total cards value (hand 0) is: 12
      
      The total cards value (hand 1) is: 18
      

      如果您的意图不是传递结构数组,那么显然不需要循环。注意:使用了两个循环。第一个得到双手的牌,第二个计算双方的分数。 (你可以用一张来做,但看起来你打算在得分之前输入所有卡片)检查一下,如果你还有其他问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 2017-08-27
        • 2014-04-09
        • 2013-02-23
        • 1970-01-01
        • 2015-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多