【问题标题】:C Blackjack Lab, pointer problemsC Blackjack Lab,指针问题
【发布时间】:2018-05-21 21:37:55
【问题描述】:

很抱歉,这不是应有的详细信息,但我实在是太赶时间了。我正在尝试编写一个程序,该程序使用代表输入文件中的牌的字符(模拟一副牌)来模拟二十一点游戏。我还没有完成,但正如我所说,我几乎没有时间输入这个。我在使用指针方面特别有问题,以及涉及 main() 中的“if”语句的错误代码。它说ranOut(应该用于在文件用完卡片时结束游戏,在文件中表示为0)抛出异常:读取访问冲突,nullptr。如果这是微不足道的,我很抱歉,但我还是 C 的新手,指针是我存在的祸根。这是我的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


FILE *fpOut;
FILE *fpIn;

#define TRUE 1
#define FALSE 0

int playHand(int *dealerTotal, int *playerTotal, int *ranOut); //Plays one hand

int getCard(int total); //Reads next card from input, assigns value to points

int main() {

if (!(fpOut = fopen("csis.txt", "w")))
{
    printf("csis.txt could not be opened for output.");
    exit(1);
}


if (!(fpIn = fopen("cards.txt", "r")))
{
    printf("cards.txt could not be opened for input.");
    exit(1);
}

int *dealerTotal = 0; //Initialize variables to count wins
int *playerTotal = 0;

int *ranOut = 0; //ends loop

while (1)
{
    playHand(dealerTotal, playerTotal, ranOut);

    if (*ranOut == TRUE)
        break;
}

printf("Total Dealer Wins: %d", *dealerTotal);
printf("Total Player Wins: %d", *playerTotal);

fclose(fpIn);
fclose(fpOut);
getchar();

return 0;
}

int playHand(int *dealerTotal,int *playerTotal, int *ranOut)
{
int pCard[10] = { 0 };
int dCard[10] = { 0 };
int dWin = 0;
int pWin = 0;
int i = 0;
int dFin = 0;
int pFin = 0;

while (i < 10)
{
    int sumP = pCard[0] + pCard[1] + pCard[2] + pCard[3] + pCard[4] + 
pCard[5] + pCard[6] + pCard[7] + pCard[8] + pCard[9];
    int sumD = dCard[0] + dCard[1] + dCard[2] + dCard[3] + dCard[4] + 
dCard[5] + dCard[6] + dCard[7] + dCard[8] + dCard[9];

    if (sumP <= 15)
    {
        pCard[i] = getCard(sumP);
    }
    else
        pFin = TRUE;
    if (sumD <= 16)
    {
        dCard[i] = getCard(sumD);
    }
    else
        dFin = TRUE;

    if (pCard[i] == 42 || dCard[i] == 42)
    {
        *ranOut = TRUE;
        break;
    }

    sumP = pCard[0] + pCard[1] + pCard[2] + pCard[3] + pCard[4] + pCard[5] + 
pCard[6] + pCard[7] + pCard[8] + pCard[9];
    sumD = dCard[0] + dCard[1] + dCard[2] + dCard[3] + dCard[4] + dCard[5] + 
dCard[6] + dCard[7] + dCard[8] + dCard[9];

    if (sumP > 21 || sumD == 21)
    {
        dWin = TRUE;
        pWin = FALSE;
    }
    else if (sumD > 21 || sumP == 21)
    {
        dWin = FALSE;
        pWin = TRUE;
    }
    else if (dFin && pFin)
    {
        if ((21 - sumP) > (21 - sumD))
        {
            dWin = TRUE;
            pWin = FALSE;
        }
        else
        {
            dWin = FALSE;
            pWin = TRUE;
        }
    }



    if (dWin)
    {
        *dealerTotal++;
        break;
    }
    else if (pWin)
    {
        *playerTotal++;
        break;
    }

    i++;
} 

return 1;

}

int getCard(int total)
{
char x;
int y = 0;


if (!feof(fpIn))
{
    x = fgetc(fpIn);
    switch (x) 
    {
        case '0':
            y = 42;
            break;

        case '1':
            y = 1;
            break;
        case '2':
            y = 2;
            break;
        case '3':
            y = 3;
            break;
        case '4':
            y = 4;
            break;
        case '5':
            y = 5;
            break;
        case '6':
            y = 6;
            break;
        case '7':
            y = 7;
            break;
        case '8':
            y = 8;
            break;
        case '9':
            y = 9;
            break;
        case 'T':
            y = 10;
            break;
        case 'K':
            y = 10;
            break;
        case 'Q':
            y = 10;
            break;
        case 'J':
            y = 10;
            break;
        case 'A':
            if(total > 10)
            y = 1;
            else if (total >= 10)
                y = 11;
            break;
    }
}
return y;
}

【问题讨论】:

  • 当您遇到此类错误时,第一步是将代码放入调试器中。需要注意的一件事是 int *x = 0 不是初始化事物的推荐方式。在 C 中应该是 int *x = NULL.
  • 这段代码还需要:更好的缩进、模块化、通过使用循环减少重复代码、查找表来替换庞大的case 语句等等。

标签: c nullptr


【解决方案1】:
int *ranOut = 0; //ends loop

这声明了一个指向0的整数指针,所以它是一个NULL指针。

尝试将ranOut 声明为整数

int ranOut = 0; //ends loop

然后将其地址传递给playHand()

playHand(dealerTotal, playerTotal, &ranOut);

当然,在Main() 中以整数形式访问它

if (ranOut == TRUE)

【讨论】:

    【解决方案2】:

    你应该选择:

    1. 将 ranOut 用作 int * 并因此使用 malloc 在堆上为其动态分配空间。
    2. ranOut 用作int 并将其地址&amp;ranOut 传递给需要指针的函数。

    对我来说,第二个选项听起来更容易实现。但是第一种是推荐的方式

    int realRanOut;
    int *ranOut;
    ranOut = &realRanOut;
    

    所以ranOut 现在指向一个初始化的内存区域。

    【讨论】:

      猜你喜欢
      • 2010-11-15
      • 2011-08-02
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多