代码在调试器中工作,但不在可执行程序中

时间:2013-07-27 20:31:11

标签: c++ c

我在Win7 x64上的4.7.2上使用MinGW GCC

这是练习:

http://postimg.org/image/v4xnpcxc3/

这是我未完成的代码(没有有效的退出循环条件)不起作用(字母永远不会出一行或一列。我试图调试程序和调试器代码工作?? !!):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

int main(void)
{
    char array[10][10];
    int direction = 0;
    int i = 0, j = 0, cnt = 1;
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            array[i][j] = '*';
        }
    }
    int z = 200;
    array[i][j] = 'A';
    while(z-- > 0)
    {
        srand((unsigned)time(NULL));
        direction = rand() % 4;
        switch(direction)
        {
            case 0:
                if(i != 0)
                    i--; 
                break;
            case 1:
                if(j != 9)
                    j++; 
                break;
            case 2:
                if(i != 9)
                    i++;
                break;
            case 3:
                if(j != 0)
                    j--;
                break;
        }
        if(array[i][j] == '*')
        {
            array[i][j] = 'A' + cnt;
            cnt++;
        }       
        if(cnt == 26)
            break;
    } 
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
           printf("%c ", array[i][j]);
        }
        printf("\n");
    }
}

3 个答案:

答案 0 :(得分:2)

第一

  array[i][j] = 'A';

实际上与array[0][0] = 'A';相同:

for(int i = 0; i < 10; i++)

for(int j = 0; j < 10; j++)

隐藏ij之前的声明:

int i = 0, j = 0, cnt = 1;

其次,在循环中srand之前调用rand是不好的。在程序开始时只调用srand一次。

答案 1 :(得分:1)

出于好奇,我努力用C ++代码解决这个问题。我想我也可以分享这些努力。

我选择了

  • 取消多维数组(这使IMO更容易)
  • 通过显示正在发生的反向跟踪来使事物可调试

请注意,我对lambdas的使用“隐藏”了我的方法的OO启发性质。

  • apply()rollback()代理history(pos, pending)
  • select()尝试从当前(pos, board)生成有效的未经验证的移动,如果成功则返回true

其余内容记录在案。

Live on Coliru

#include <functional>
#include <random>
#include <array>
#include <iostream>
#include <set>
#include <deque>

typedef int pos_t;
static const char Empty = '.';

enum direction : int { N = -10, S = 10, E = 1, W = -1, None = 0 };

std::ostream& operator<<(std::ostream& os, direction d);

direction random_direction()
{
    static const std::array<direction, 4> steps { { N, S, E, W } };
    static auto gen = std::bind(std::uniform_int_distribution<int>(0,steps.size()), std::mt19937(time(NULL)));
    return steps[gen()];
}

struct move
{
    direction           taken = None;
    std::set<direction> tried;
};

int main()
{
    std::vector<char> board(100, Empty);

    pos_t pos    = 0;
    char station = 'A';
    board[pos]   = station++;

    // generate moves
    std::deque<move> history {}; // start with an empty move
    move pending {};

    auto select = [&] () -> bool
    { 
        auto& taken = pending.taken;
        auto& tried = pending.tried;

        pos_t nw;

        do
        {
            // random untried direction
            do    taken        = random_direction();
            while (end(tried) != tried.find(taken));

            // calculate new position
            nw = pos + taken;

            // validate new position
            bool valid = 
                (nw>=0) && (nw<(int)board.size()) && // within bounds?
                board[nw]==Empty &&                  // unvisited?
                // detect moving across the edge using invariant: 
                // INV: only col/row allowed to change
                ((pos%10 == nw%10) != (pos/10 == nw/10));

            // mark tried
            tried.insert(taken);

            // return if valid/no candidates
            if (valid || 4 == tried.size())
                return valid;

        } while (true); // try another direction
    };

    auto display = [&] {
        for(auto row = begin(board); row<end(board); row+=10)
            std::cout << std::string(row, row+10) << "\n";
    };

    auto apply = [&] () mutable {
        std::cout << pending.taken;

        pos        += pending.taken;
        board[pos]  = station++;

        history.emplace_back();
        std::swap(pending, history.back());
        //display();
    };

    auto backtrack = [&] () mutable {
        std::swap(pending, history.back());
        history.pop_back();
        std::cout << "[-" << pending.taken << "]";

        board[pos]  = (--station, Empty);
        pos        -= pending.taken;
        //display();
    };

    // game loop
    std::cout << "\nGenerating: ";

    while (station<='Z')
        select()? apply() : backtrack();

    std::cout << "\nResulting board: \n";

    display();
}

std::ostream& operator<<(std::ostream& os, direction d)
{
    switch(d) {
        case N : return os << 'N';
        case S : return os << 'S';
        case E : return os << 'E';
        case W : return os << 'W';
        default: break;
    };
    return os << "?";
}

示例运行:

Generating: ESW[-W]EN[-N]SSSENENWNEESSSWSEESESE
Resulting board: 
AB........
.CDMNO....
..ELKP....
..FIJQ....
..GHSR....
....TUV...
......WX..
.......YZ.
..........
..........
Generating: SENESEENW[-W]EESSWWWSESSESWWSS
Resulting board: 
ADE.IJK...
BCFGH.L...
...PONM...
...QR.....
....S.....
....TU....
...XWV....
...Y......
...Z......
..........

答案 2 :(得分:0)

调试器通常清除数据,即将变量设置为零。如果您检查例如NULL指针,但忘记初始化您检查的变量,然后它将在调试器中工作,但在调试器外运行程序时则不行。