Приём двумерного массива из функции???

Вопрос по двумерным массивам. Имеется файл map.cpp с функцией map_making(), результат её работы – двумерный массив map[ ][ ]. Не знаю как его передать в main.cpp, а главное как его там правильно принять?
Ошибку выдаёт: инициализация: невозможно преобразовать «char» в «char [24][50]»

// main.cpp

#include <iostream>
#include "conio.h"
#include "map.h"

using namespace std;

int main()
{
    char map[width][length] = map_making(); // получение массива

    for(int i=0; i<width; i++) // выводим массив на экран
    {
        for(int j=0; j<length; j++)
            cout << map[i][j];
        cout << endl;
    }


    _getch();
}

// map.h

#ifndef MAP_H
#define MAP_H

    char map_making(); // Построение двумерного массива

    const unsigned short length = 50; // кол-во столбцов массива
    const unsigned short width = 24; // кол-во строк массива
    char map[width][length]; // массив

#endif

// map.cpp

#include "map.h"

char map_making() // Построение двумерного массива
{
  /*
  тело функции
            */

    return map[width][length];
}

Я так понимаю, что константы length и width должны быть доступны в main.cpp раз подключен заголовочный файл, поэтому использую их там для объявления размера массива. Или это ошибка?

Правильно ли выглядит синтаксис:

 return map[width][length];

И как должен правильно выглядеть приём массива:

char map[width][length] = map_making(); // получение массива

И отдельный вопрос по map.h. Создаваемый массив является объектом с постоянным содержимым, поэтому по моему разумению создавать class бессмысленно. Правильно ли тогда выглядит оформление map.h?

Slonopotam, тут у тебя есть несколько нестыковок.

(1) Ты спланировал, что двумерный массив map должен существовать глобально. Это у тебя не получилось правильно реализовать, но пока не об этом. Если map глобален и видим в других файлах проекта через заголовочный файл map.h, то ни передавать его в функцию, ни возвращать его из функции, ни переприсваивать его в функции main другой переменной (совершенно варварским методом) не надо. Он и так доступен и в main(), и в map_making(). Поэтому первый, третий и четвёртый вопросы снимаются как бы сами собой.

(2) Результатом работы map_making() является не массив, а заполнение массива некими данными. Точность формулировок здесь важна: от них зависит суть вопроса.

(3) Что неправильно в файле map.h и как правильно определить двумерный массив map?

Неправильно всё, за исключением директив условной компиляции ))

Как уже выяснилось, функция map_making() не должна ничего возвращать. Поэтому сигнатура функции будет немного иной.

Есть такое правило хорошего тона: заголовочный файл не должен порождать исполняемого кода. В данном случае исполняемый код порождают определения констант и определение массива (здесь это выделение памяти и инициализация). Что при этом получается? Мы включаем файл map.h в файл main.cpp, и в файл map.cpp. При компиляции main.cpp и map.cpp константы и массив будут существовать в обоих объектных файлах, что приведёт к ошибке при сборке: линкер не сможет разобраться с двумя копиями одних и тех же переменных и констант.

Выход из этой ситуации: в заголовочном файле необходимо сделать только объявления переменных, а в файле кода (.cpp) — их определения.

Здесь натыкаемся ещё на один камень: если определения констант (т.е. конкретные числовые значения) поместить в .cpp-файл, то они не будут видны в заголовочном файле и, следовательно, компилятор не сможет определить размерности массива. Выход: вместо константных переменных использовать #define.

Исходя из вышесказанного, файлы map.h и map.cpp будут выглядеть так:
map.h

#ifndef MAP_H
#define MAP_H

#define LENGTH 50
#define WIDTH 24

// Объявление массива. Память не выделяется из-за спецификатора extern.
extern char map[WIDTH][LENGTH];

void map_making(); // Заполнение данными двумерного массива.

#endif

map.cpp

#include "map.h"

// Определение массива. Здесь под массив резервируется память.
char map[WIDTH][LENGTH];

void map_making() // Заполнение данными двумерного массива.
{
    // для примера так:
    for (int i = 0; i < WIDTH; i++)
        for (int j = 0; j < LENGTH; j++)
            map[i][j] = (i + j) % 2 ? '-' : 'o';
}

Соответственно вносим изменения в main.cpp:

#include <iostream>
#include <conio.h>    // здесь лучше использовать <> вместо кавычек
#include "map.h"

using namespace std;

int main()
{
    map_making(); // инициализация массива значениями

    for (int i = 0; i < WIDTH; i++) // выводим массив на экран
    {
        for (int j = 0; j < LENGTH; j++)
            cout << map[i][j];
        cout << endl;
    }

    _getch();
}

Дополнительно можешь ещё почитать статью Многомерные массивы в C++ — практическое пособие.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.