【问题标题】:transform a one dimension Array into two dimension in Mac doesn't work在Mac中将一维数组转换为二维不起作用
【发布时间】:2014-10-28 07:05:26
【问题描述】:

我参加了一门 C++ 课程,与我的所有学生不同,我购买了一台使用 xcode 运行和编辑文件的 Mac。但是最近有一段代码,在Ubuntu系统下可以很好的运行,但是在我的mac上,一直报错。

错误出现在这一行:char (*maze)[width] = reinterpret_cast (m_maze); 并且有 3 行与上述内容相同。如果你在 Ubuntu 中使用代码,它运行成功,但在 mac 中,它终止并报告 3 个相同的错误。

警告说:不能用 'char()[width]' 的右值初始化类型 'char()[width]' 的类型

请帮忙

代码是关于迷宫中的鼠标。 以下是代码:

#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <cstdio>
using namespace std;
const char MOUSE  = '*';
const char WAY    = ' ';
const char WALL   = '@';
const char PASS   = '.';
const char IMPASS = 'X';
typedef enum tag_Direction {
    EDIR_RIGHT,
    EDIR_DOWN,
    EDIR_LEFT,
    EDIR_UP
}   EDIR;
class Stack {
public:
    Stack (void) : m_top (NULL) {}
    ~Stack (void) {
        for (Node* next; m_top; m_top = next) {
            next = m_top -> m_next;
            delete m_top;
        }
    }
    void push (EDIR dir) {
        m_top = new Node (dir, m_top);
    }
    EDIR pop (void) {
        if (! m_top)
            throw underflow_error ("Underflow of Stack!");
        EDIR dir = m_top -> m_dir;
        Node* next = m_top -> m_next;
        delete m_top;
        m_top = next;
        return dir;
    }
private:
    class Node {
    public:
        Node (EDIR dir, Node* next) : m_dir (dir),
        m_next (next) {}
        EDIR m_dir;
        Node* m_next;
    };
    Node* m_top;
};
class Mouse {
public:
    Mouse (size_t x, size_t y) : m_x (x), m_y (y),
    m_total (0), m_valid (0) {}
    size_t getx (void) const {
        return m_x;
    }
    size_t gety (void) const {
        return m_y;
    }
    size_t gettotal (void) const {
        return m_total;
    }
    size_t getvalid (void) const {
        return m_valid;
    }
    void stepright (void) {
        m_x++;
        remember (EDIR_RIGHT);
    }
    void stepdown (void) {
        m_y++;
        remember (EDIR_DOWN);
    }
    void stepleft (void) {
        m_x--;
        remember (EDIR_LEFT);
    }
    void stepup (void) {
        m_y--;
        remember (EDIR_UP);
    }
    void stepback (void) {
        switch (recall ()) {
            case EDIR_RIGHT:
                m_x--;
                break;
            case EDIR_DOWN:
                m_y--;
                break;
            case EDIR_LEFT:
                m_x++;
                break;
            case EDIR_UP:
                m_y++;
                break;
        }
    }
private:
    void remember (EDIR dir) {
        m_brain.push (dir);
        m_total++;
        m_valid++;
    }
    EDIR recall (void) {
        EDIR dir = m_brain.pop ();
        m_total++;
        m_valid--;
        return dir;
    }
    size_t m_x;
    size_t m_y;
    size_t m_total;
    size_t m_valid;
    Stack m_brain;
};
class Game {
public:
    Game (size_t width, size_t height) :
    m_width (width), m_height (height),
    m_maze (new char[width * height]),
    m_mouse (0, 1) {
        if (height < 3)
            throw invalid_argument ("The maze is too small!");
        srand (time (NULL));
        char (*maze)[width] = reinterpret_cast<char (*)[width]> (m_maze);**
        for (size_t i = 0; i < height; i++)
            for (size_t j = 0; j < width; j++)
                if (i == m_mouse.gety () &&
                    j == m_mouse.getx ())
                    maze[i][j] = MOUSE;
                else
                    if ((i == 1 && j < 4) ||
                        (i == height - 2 && j >width-5))
                        maze[i][j] = WAY;
                    else
                        if (i == 0 || i == height - 1 ||
                            j == 0 || j == width - 1)
                            maze[i][j] = WALL;
                        else
                            maze[i][j] =
                            rand () % 4 ? WAY : WALL;
    }
    ~Game (void) {
        if (m_maze) {
            delete[] m_maze;
            m_maze = NULL;
        }
    }
    void run (void) {
        for (show (); ! quit () && step (););
    }
private:
    void show (void) {
        char (*maze)[m_width] = reinterpret_cast<char (*)[m_width]> (m_maze);
        for (size_t i = 0; i < m_height; i++) {
            for (size_t j = 0; j < m_width; j++)
                cout << maze[i][j];
            cout << endl;
        }
        cout << "Total steps:" << m_mouse.gettotal ()
        << ",Valid steps:" << m_mouse.getvalid ()
        << endl;
    }
    bool quit (void) {
        cout << "Press<Q>to exit,Other keys to continue..."<<flush;
        int ch = getchar ();
        cout << endl;
        return ch == 'Q' || ch == 'q';
    }
    bool step (void) {
        char (*maze)[m_width] = reinterpret_cast<char (*)[m_width]> (m_maze);
        size_t x = m_mouse.getx ();
        size_t y = m_mouse.gety ();
        if (x + 1 <= m_width - 1 && maze[y][x + 1] == WAY) {
            maze[y][x] = PASS;
            m_mouse.stepright ();
        }
        else
            if (y + 1 <= m_height - 1 &&
                maze[y + 1][x] == WAY) {
                maze[y][x] = PASS;
                m_mouse.stepdown ();
            }
            else
                if (x - 1 >= 0 &&
                    maze[y][x - 1] == WAY) {
                    maze[y][x] = PASS;
                    m_mouse.stepleft ();
                }
                else
                    if (y - 1 >= 0 &&
                        maze[y - 1][x] == WAY) {
                        maze[y][x] = PASS;
                        m_mouse.stepup ();
                    }
                    else {
                        maze[y][x] = IMPASS;
                        m_mouse.stepback ();
                    }
        x = m_mouse.getx ();
        y = m_mouse.gety ();
        maze[y][x] = MOUSE;
        show ();
        if (x == 0 && y == 1) {
            cout << "I can't get out!cry~~~~" << endl;
            return false;
        }
        if (x == m_width - 1 && y == m_height - 2) {
            cout << "I am OUT!!!" << endl;
            return false;
        }
        return true;
    }
    size_t m_width;
    size_t m_height;
    char* m_maze;
    Mouse m_mouse;
};
int main (int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "Method:" << argv[0] << " <width> <height>"
        << endl;
        return -1;
    }
    try {
        Game game (atoi (argv[1]), atoi (argv[2]));
        game.run ();
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
}

【问题讨论】:

  • Mac 上报什么错误?
  • 打开所有编译器警告 (-Wall -Wextra -Wpedantic -Weffc++) 并修复警告,代码中有很多草率的结构,修复它们可能会解决问题。
  • 警告说:不能用 'char()[width]' 的右值初始化类型 'char()[width]' 的类型

标签: c++ arrays pointers c++11


【解决方案1】:
char (*maze)[width] = reinterpret_cast<char (*)[width]> (m_maze);

不标准:警告:ISO C++ 禁止变长数组“迷宫”[-Wvla]。

你必须使用

m_maze[y * width + x]

而不是

maze[y][x]

【讨论】:

  • 实际上如果你可以将代码复制到你的xcode中,只是将char *转换为char数组*有问题。它与:m_maze[y*width + x] 或 maze[y][x] 无关
  • @ToxJia:因为你不能拥有char (*maze)[width],所以你不能再使用maze[y][x]
  • 所以在 Xcode 中,我不能使用 reinterpret_cast 将 char 指针转换为 char 数组指针?
  • @ToxJia:如果在编译时数组大小未知,则不是(按标准但可能按扩展)。
猜你喜欢
  • 2020-03-26
  • 2016-02-18
  • 2018-02-19
  • 2015-11-27
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多