调用 second* 函数时程序软锁定

Posted

技术标签:

【中文标题】调用 second* 函数时程序软锁定【英文标题】:Program soft-locking when calling second* function 【发布时间】:2015-11-07 11:52:18 【问题描述】:

所以,我正在通过编写一个程序来练习我的 C++ 代码,该程序在用户指​​定大小的网格中创建一个配对游戏。为此,我将每个操作(初始化网格、绘制网格、隐藏对以及从用户输入中查找对)分离到一个函数中。 不幸的是,在某些时候——我不知道何时或如何——程序开始无法调用第二个*和后续函数。在调用drawGrid 后,它应该立即转到hidePairs - 但是,它只是在该步骤停止。命令窗口中的光标一直在闪烁,所以程序运行得很好,但我无能为力。 我已经通过调试进行了检查,它确实成功地执行了drawGrid 并移动到main 的下一行,但是没有更多的代码被执行。我做错了什么?

*EDIT:第三个函数,它成功绘制了网格,然后在隐藏对之前停止。为了清晰起见,删除了不必要的引用调用并添加了所有功能。我的坏:P

#include <iostream>
#include <random>
#include <algorithm>


void drawGrid(int gridX, int gridY, char gridArray[][30]);
void hidePairs(int gridX, int gridY, char pairsArray[][30], int *numPairs);
void findPairs(int gridX, int gridY, char gridArray[][30], char pairsArray[][30], int *numPairs);
void initialiseGrid(int gridX, int gridY, char gridArray[][30], char pairsArray[][30]);

int main()

    int gridX, gridY, numPairs;

    //Ask user for gridX(width) and gridY(height)
    std::cout << "Please enter the width and height of the grid you want to use." << std::endl;

    bool gridIsNotEven = true;
    while (gridIsNotEven == true)
    
        std::cin >> gridX >> gridY;
        if ((gridX*gridY) % 2 == 0)
        
            gridIsNotEven = false;
        
        else
        
            std::cout << std::endl << "The grid produced by these two numbers has an odd number of spaces." << std::endl;
        
    
    if (gridX*gridY > 30)
    
        std::cout << "This grid is larger than recommended." << std::endl;
    
    gridX++;
    gridY++;
    char gridArray[30][30];
    char pairsArray[30][30];
    numPairs = ((gridX*gridY) / 2);

    //Func : initialiseGrid
    initialiseGrid(gridX, gridY, gridArray, pairsArray);

    //Func : drawGrid
    drawGrid(gridX, gridY, gridArray);

    //Func : hidePairs
    hidePairs(gridX, gridY, pairsArray, &numPairs);

    //Func : findTreasure
    findPairs(gridX, gridY, gridArray, pairsArray, &numPairs);

    system("Pause");
    return 0;


void drawGrid(int gridX, int gridY, char gridArray[][30])

    int printX, printY;

    //For(printX = 0, printX < gridX, printX++)
    for (printY = 0; printY < gridY; printY++)
    
        //For(printY = 0, printY < gridY, printY++)
        for (printX = 0; printX < gridX; printX++)
        
            std::cout << gridArray[printX][printY] << " ";
        
        //END FOR

        //Print new line
        std::cout << std::endl;
    
    //END FOR


void hidePairs(int gridX, int gridY, char pairsArray[][30], int *numPairs)

    int pairsMade, halfPair, curPairX = 0, curPairY = 0;
    char pairSymbol = '!';

    for (pairsMade = 0; pairsMade < *numPairs; pairsMade++)
    
        halfPair = 0;
        while (halfPair < 2)
        
            curPairX = rand() % gridX;
            curPairY = rand() % gridY;
            if (pairsArray[curPairX][curPairY] == '?')
            
                pairsArray[curPairX][curPairY] = pairSymbol;
                halfPair++;
            
        
        pairSymbol++;
    


void findPairs(int gridX, int gridY, char gridArray[][30], char pairsArray[][30], int *numPairs)

    int guess1X = 0, guess1Y = 0, guess2X, guess2Y, printChar, pairsFound = 0;
    //Display pairs
    char pairSymbol = '!';
    printChar = 0;
    std::cout << std::endl << "The following symbols will be used in the grid:" << std::endl << std::endl;

    while (printChar < *numPairs)
    
        std::cout << pairSymbol << std::endl;
        pairSymbol++;
        printChar++;
    
    //while ((guessX != treasureX) OR(guessY != treasureY))
    while (pairsFound != *numPairs)
    
        //  User input : guessX and guessY
        std::cout << std::endl << "Please enter the co-ordinates of your first guess (e.g. 'X Y')" << std::endl << std::endl;
        std::cin.clear();

        std::cin >> guess1X >> guess1Y;
        gridArray[guess1X][guess1Y] = pairsArray[guess1X][guess1Y];
        drawGrid(gridX, gridY, gridArray);

        std::cout << std::endl << "Please enter the co-ordinates of your second guess (e.g. 'X Y')" << std::endl << std::endl;
        std::cin.clear();

        std::cin >> guess2X >> guess2Y;
        gridArray[guess2X][guess2Y] = pairsArray[guess2X][guess2Y];
        drawGrid(gridX, gridY, gridArray);

        if (guess1X > gridX || guess1X < 1 || guess1Y > gridY || guess1Y < 1)
        
            std::cout << std::endl << guess1X << ", " << guess1Y << " does not lie inside the grid. Try again." << std::endl;
            continue;
        
        else if (gridArray[guess1X][guess1Y] == gridArray[guess2X][guess2Y])
        
            pairsFound++;
        
        else
        
            std::cout << std::endl << "Pair not matching" << std::endl << std::endl;
            gridArray[guess1X][guess1Y] = '?';
            gridArray[guess2X][guess2Y] = '?';
        

        //      END IF
    
    //Print ‘Success! etc.’
    std::cout << std::endl << "Success! You found all the pairs!" << std::endl << std::endl;


void initialiseGrid(int gridX, int  gridY, char gridArray[][30], char pairsArray[][30])

    int printX, printY;
    for (printY = 0; printY < gridY; printY++)
    
        for (printX = 0; printX < gridX; printX++)
        
            if ((printX == 0))
            
                gridArray[0][printY] = printY + '0';
                pairsArray[0][printY] = printY + '0';
            
            else if ((printY == 0))
            
                gridArray[printX][0] = printX + '0';
                pairsArray[printX][0] = printX + '0';
            
            else
            
                gridArray[printX][printY] = '?';
                pairsArray[printX][printY] = '?';
            
        
    

【问题讨论】:

为什么将所有参数都作为指针传递? 这只是我养成的习惯。诚然,它们中的许多都可以用作按值传递,但即便如此,这似乎也不是这里的问题。 什么输入失败了? if (gridX*gridY &gt; 30) 应该是 if (gridX &gt; 30 || gridY &gt; 30) 但这也不是崩溃的原因。 好的,我已将所有不必要的引用更改为值传递,并使数组名称在声明、定义和传递中匹配。输出仍然相同,只是在第一次绘制网格后停止。 (我之前犯了一个错误,当我说它在drawGrid 被调用之前就停止了) 您可能在未显示的代码中某处存在无限循环。如果在绘制网格后直接输入cout 会发生什么? 【参考方案1】:

您将配对数初始化为numPairs = gridX * gridY / 2,但该大小(gridXgridY)还包含标题列和行,它们在配对中不起作用。 所以要解决这个问题,你的numPairs 应该是(gridX-1) * (gridY-1) / 2。 否则,配对会用尽,但配对功能仍在寻找!这是你的无限循环。

我还建议您为 gridXgridY 找到一个更好的名称,以表明标头已被计算在内,或者在您的其余代码中要非常小心,以便您了解 gridXgridY 的含义意思是网格只在索引1而不是索引0处开始成为实际事物。

【讨论】:

谢谢!啊,老生常谈的问题。老实说,我很惊讶有人能理解我的代码,它的布局如此糟糕!我会接受关于变量命名的建议,听起来这对我未来有很大帮助。再次感谢! @ChipBiscuit 这实际上是相当可读的代码;东西很好地分解成函数,全面的变量名(除了这个混淆),没有全局变量,而是参数传递,使其更具可读性。【参考方案2】:

仅当您添加由数组大小引起的 30 或更高的数字时,它才会失败 我不知道您的设置,但请确保您具有 GNU C++11 等语言标准的编译器设置

它应该可以工作

【讨论】:

【参考方案3】:

原来在 hidePairs 函数中有一个无限循环。它没有读取pairArray中的正确坐标,因此它永远不会填充空格。并且由于循环仅在所有未使用的空格都被填充时才设置为结束,因此它永远不会停止。 对其他人的建议:始终检查您的循环!

【讨论】:

以上是关于调用 second* 函数时程序软锁定的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 检测应用程序何时发送到后台而不是设备锁定时

在Android中锁定屏幕时未调用BroadcastReceiver

std::mutex 锁定的顺序

正在运行100个以上时锁定asyncio函数?

访问被 Azure AD B2C 锁定的 Azure 函数应用时收到 403 错误

屏幕锁定时会停止WebView媒体内容(调用活动的onStop)