Как правильно инициализировать многомерный массив символов и передать его функции? - PullRequest
3 голосов
/ 29 апреля 2011

Я пишу программу, которая находит выход из лабиринта. У меня есть многомерный массив, представляющий фактический лабиринт.

const int size = 12;
    char maze[ size ][ size ] = {
            "############",
            "#...#......#",
            "..#.#.####.#",
            "###.#....#.#",
            "#....###.#..",
            "####.#.#.#.#",
            "#..#.#.#.#.#",
            "##.#.#.#.#.#",
            "#........#.#",
            "######.###.#",
            "#......#...#",
            "############",
        };

VS C ++ выдает мне предупреждающее сообщение о том, что размер слишком мал для такого массива. Я думаю, это потому, что в каждой строке также должен быть символ «\ 0». Как инициализировать массив символов без символов \ 0? Я не хочу инициализировать size значением 13, потому что он будет слишком запутан, чтобы использовать эту константу для функций (массив печати, перемещение и т. Д.). Есть ли способ сделать это?

Кроме того, как передать этот массив в функцию void mazeTraverse, используя указатель?

int main()
{
  mazetraverse(maze)
}

void mazeTraverse(char (*maze)[ size ])

Такой код не работает ...

Ответы [ 4 ]

3 голосов
/ 29 апреля 2011

Вам необходимо учесть символ NULL в конце строки:

char maze[size][size + 1] = { /*  */ };

В качестве альтернативы для большей гибкости вы можете сделать:

char *maze[size] = { /*  */ };

Iвижу, что вы используете C ++.Есть ли причина, по которой вы не используете std::string?

std::string maze[size] = { /*  */ };

Это гораздо более гибко;теперь вы просто измените прототип на:

void mazeTraverse(std::string maze[]);

Если вы еще более безумны, вы будете использовать std::vector<std::string>.


EDIT: Я рекомендую немного узнать о std::string.Он работает так же, как char*, но вам не нужно его выделять вручную и т. Д.Например:

std::string mystring = "lol";
mystring = "lololol"; // perfectly legal!

std::cout << mystring[0] << "\n";
// Or: printf("%c\n", mystring[0]);

char* sz[8];
strcpy(sz, mystring[0].c_str());

// And so on...
2 голосов
/ 29 апреля 2011

Пока вы используете C ++, почему бы просто не создать простой класс?:

class Maze {
  public:
    Maze(int width, const std::string& data) 
      :width_(width),
       data_(data.begin(), data.end()) {
    }

    char operator()(int row, int column) const { 
      return data_[width_*row + column]; 
    }

  private:
    int width_;
    std::vector<char> data_;
};

Вы можете легко инициализировать его, воспользовавшись тем, что последующие строковые литералы, такие как "foo" и "bar", неявно объединяются в "foobar":

Maze my_maze(12, 
             "############"
             "#...#......#"
             "..#.#.####.#"
             "###.#....#.#"
             "#....###.#.."
             "####.#.#.#.#"
             "#..#.#.#.#.#"
             "##.#.#.#.#.#"
             "#........#.#"
             "######.###.#"
             "#......#...#"
             "############");
1 голос
/ 29 апреля 2011

«Не работает»? Код работает . И это прекрасно работает. (Предполагая, что компилятор позволяет использовать эти 13-символьные строковые литералы для инициализации массивов размера 12. На самом деле это ошибка в C ++, но вы сказали, что получаете простое предупреждение).

Это

mazeTraverse(maze);

скомпилирует и сделает именно то, что вы хотите, чтобы он делал (как я понимаю). Что именно не работает в вашем случае? «Не работает» - не совсем содержательное описание проблемы.

Что касается избавления от предупреждения при инициализации массива, если вы настаиваете на наличии массива точного размера, вам придется инициализировать его по-символьно, как в

char maze[ size ][ size ] = {
  { '#', '#', '#', ... },
  { ...                },
  // and so on
};

Если вы хотите использовать строковые литералы, то, как вы сами отметили, вы должны объявить внутренние подмассивы большего размера

char maze[ size ][ size + 1 ] = {
  "############",
  // and so on
};

и соответственно изменить объявление функции

void mazeTraverse(char (*maze)[ size + 1 ])
0 голосов
/ 29 апреля 2011

Для инициализации я бы:

char* maze[ size ] = {
        "############",
        "#...#......#",
        "..#.#.####.#",
        "###.#....#.#",
        "#....###.#..",
        "####.#.#.#.#",
        "#..#.#.#.#.#",
        "##.#.#.#.#.#",
        "#........#.#",
        "######.###.#",
        "#......#...#",
        "############",
    };

Для передачи параметров вы должны использовать char **. Так что это будет:

void mazeTraverse(char ** param)
...