2017-04-02 63 views
1

我會通過一些C編程的問題,我目前停留在一個指針相關的問題增加價值 - 用指針和結構

問:編寫一個函數,需要一個雙值卡二十一點HAND作爲輸入,並返回手的積分。牌'2'到'9'的值爲 等於它們的面值,牌'T','K','Q','J'值10分,而ace('A')是值得11分 除非它與另一個王牌,那麼第二個王牌是值得1分。該程序應該能夠捕捉到不正確的輸入。

例子: 輸入卡:AQ 得分爲21

輸入卡:AA 得分爲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; 
} 
+0

你現在面對的是什麼問題? –

+0

如果您將指針傳遞給結構,則無需爲手指定參數。您可以使用指針訪問它們。 –

回答

2

你有一些錯誤。

main中的呼叫錯誤。

函數不需要大小參數,如果它確實應該是int

return來自main

在函數中,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; 
} 
+0

Jeez,謝謝你!我會查看你的代碼並研究它。真的想得到指針的竅門,但它有點艱難。 – supperforpupper

+0

不客氣!我猜想的關鍵是,只要似乎有很多複製的措詞(即通過'card = hnd_ptr-> card [idx]'簡化了允許使用'card'循環)或代碼重複[爲每個卡單獨拼寫出相同的代碼],這表明架構應該被重構。憑藉更多的經驗,您可以在初始編碼期間看到這些簡化,但是,如果您發現自己「將自己畫在一個角落」,就會發現停下來,喘口氣,重做事情。 –

0

你不及格的hnd地址功能getHandValue()。爲此,您必須使用&運算符getHandValue(&hnd)來傳遞地址。

您還未正確初始化struct player_hand hnd。有一套{}太多了。

0

這是您的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; 
} 
0

如果,除了其他的答案,你的目的是爲了傳遞一個2手數組,您需要在得分函數的循環中處理雙手。例如:

#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 

如果您的意圖是不通過結構的陣列,那麼顯然循環就沒有必要。注意:使用了兩個循環。第一個獲得雙手牌,第二個計算兩者的得分。 (你可以用一個來完成,但看起來好像你打算在得分之前輸入所有卡片)查看結果並讓我知道你是否還有其他問題。