Обрабатывать значение переменной как адрес и присваивать это значение указателю - PullRequest
0 голосов
/ 07 июня 2019

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

Вот что я сделал до сих пор.

  1. объявить указатель uint32_t * p;
  2. объявить и инициализировать две переменные

    uint32_t a = 0x0000000C; uint32_t b = 0x0C00000B;

  3. инициализировать указатель р = & а;

  4. Теперь я хочу обработать значение переменной b, равное 0x0C00000B, как адрес и поместить его в p. таким образом, указатель p теперь будет указывать на адрес 0x0C00000B. но почему-то это не работает.

Вот что я попробовал.

p = b;   doesn't work. 

p = (uint32_t *)b ; doesn't work .

После компиляции появляется одно предупреждение:

предупреждение: несовместимое преобразование целочисленного значения в указатель, присваивающее uint32_t (иначе unsigned int) из uint32_t (unsigned int); взять адрес с & [-wint- conversoin.

Проблема в том, что указатель p будет случайным образом назначен с некоторым номером вместо 0x0C00000B

Есть предложения?

Ответы [ 3 ]

1 голос
/ 07 июня 2019

«Самый правильный» способ конвертировать целое число в указатель без каких-либо предупреждений, вы должны привести к uintptr_t, затем к void*, затем к вашему типу указателя.

uint32_t b = 1;
uint32_t *p = (uint32_t*)(void*)(uintptr_t)b;

Но обычно программисты просто делают макросы , которые правильно отлиты:

#define A_ADDR  ((uint32_t*)0x0000000A)
#define B_ADDR  ((uint32_t*)0x0000000B)
uint32_t *p = A_ADDR;
p = B_ADDR;

, который компилируется без предупреждений на gcc -Wall -Wextra -pedantic.
Или иногда просто макросыс постоянными числами, и пользователь должен привести к (void*) или к правильному типу:

#define A_ADDR 0x0000000A
#define B_ADDR 0x0000000B
uint32_t *p = (uint32_t*)A_ADDR;
p = (uint32_t*)B_ADDR;

В качестве альтернативы, если вы доверяете своему компилятору, они могут быть static const переменными, напр.static const uint32_t *A_ADDR = (uint32_t*)0x0000000A;

0 голосов
/ 07 июня 2019

У вас уже есть решение - p = (uint32_t *) b; не работает Приведенная выше строка обрабатывает значение в переменной «b» как адрес и присваивает этот адрес указателю «p». Но вы можете получить некоторые предупреждения компилятора. Из моего понимания вашего варианта использования, p должен использоваться в качестве трекера в каком-то месте в памяти. Если это так, подумайте о том, чтобы написать что-то похожее на это, чтобы не выдавать никаких предупреждений -

#define TRACKER_BASE_ADDR  (0x0C00000B)
#define TRACKER_OFFSET     (0x04)
uint32_t *p = TRACKER_BASE_ADDR;
// When you want to update the tracker use this
p = p + TRACKER_OFFSET;
// And when you want to read the value at tracker,
uint32_t val = *p;

Надеюсь, это поможет

0 голосов
/ 07 июня 2019

Я понимаю вашу проблему, как показано ниже.

Вы будете хранить адрес ячейки памяти в переменной и присваивать его указателю.

В вашем примере объявить указатель uint32_t * p; объявить и инициализировать две переменные uint32_t a = 0x0000000C; uint32_t b = 0x0C00000B;

Если вы хотите узнать значение по адресу 0x0000000C, вам нужно присвоить ptr. как,

р = а; не похоже на p = & a;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...