Указатель для переменной ROM в переменной RAM?

Я делаю проект с использованием компилятора Microchip C18. У меня есть структура под названием блок, который указывает на другие блоки (северо-восток, юго-запад). Эти блоки сделают меня картой. Затем у меня есть указатель, который я использую для оценки всего.

Просто используя RAM это выглядит так:

struct block{
        struct block *north;
        struct block *east;
        struct block *south;
        struct block *west;
};


struct block map[5] =
{ // just a simple line.
        { NULL, &map[1], NULL, NULL },
        { NULL, &map[2], NULL, &map[0]},
        { NULL, &map[3], NULL, &map[2]},
        { NULL, &map[4], NULL, &map[3]},
        { NULL, NULL, NULL, &map[4]}
};


struct block* position = &map[0];

Это позволяет мне делать такие вещи, как:

void goWest()
{
if(position -> west != NULL) position = position -> west;
}

Проблема в том, что у меня не хватает оперативной памяти в моем проекте, и мне нужно использовать ПЗУ.

struct block{
        rom struct block *north;
        rom struct block *east;
        rom struct block *south;
        rom struct block *west;
};
rom struct block map[5] =
{ // just a simple line.
        { NULL, &map[1], NULL, NULL },
        { NULL, &map[2], NULL, &map[0]},
        { NULL, &map[3], NULL, &map[2]},
        { NULL, &map[4], NULL, &map[3]},
        { NULL, NULL, NULL, &map[4]}
};

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

Как мне хранить адреса переменных ROM в указателе, который я могу редактировать значения?

Когда я пытаюсь:

struct block *position = &map[0];

Я получаю "Предупреждение [2066] несоответствие квалификатора типа в назначении"

Я понимаю, что переменная ROM и RAM - это разные вещи, но я понятия не имею, что делать.

1 ответ

Решение

Какое определение для rom макрос? Я предполагаю, что это расширяется до const (и, возможно, для конкретного компилятора __attribute__ или что-то подобное), потому что компилятор жалуется на "несоответствие спецификатора типа", которое относится к const или же volatile несоответствие.

Это означает, что вы пытаетесь неявно преобразовать указатель на постоянные данные в указатель на непостоянные данные. Этот код должен генерировать то же предупреждение с вашим компилятором:

const int x = 0;
int *y = &x;  // &x is "pointer to const" but y is "pointer to non-const"

Чтобы это исправить, вам нужно заявить, что ваш position указатель является указателем на постоянные данные (которые, в зависимости от определения rom макрос, должно быть сделано либо rom или const Классификатор):

// Declare a non-constant pointer to constant data
const struct block *position = &map[0];

На каждом уровне указателя вы можете иметь const квалификатор или его отсутствие, а также для базового объекта без указателя. Итак, одноуровневый указатель может иметь 4 разных варианта:

int *x;  // Non-constant pointer to non-constant data
int *const x;  // Constant pointer to non-constant data
const int *x;  // Non-constant pointer to constant data
int const *x;  // Same as above
const int *const x;  // Constant pointer to constant data
int const *const x;  // Same as above

Обратите внимание, что int const а также const int эквивалентны, но в противном случае размещение const имеет значение.

Другие вопросы по тегам