Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C для начинающих

Войти
Регистрация
Восстановить пароль
 
 
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
#1

Что означает *(uint8_t*)(&pbuf)? - C (СИ)

07.01.2017, 23:14. Просмотров 883. Ответов 22
Метки нет (Все метки)

Всем привет,
C
1
2
uint8_t *pbuf
uint8_t memtype;
Что делается в выражении
C
1
  memtype = *(uint8_t*)(&pbuf);
???
Спасибо.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2017, 23:14
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Что означает *(uint8_t*)(&pbuf)? (C (СИ)):

Что означает строчка кода val = val & 0xF; ? - C (СИ)
Что означает строчка кода? val = val & 0xF; Не понятно использование оператора &

Что означает while (lock) - C (СИ)
объясните пожалуйста, что означает while (lock);? Я знаю примеры циклов WHile(a>5) например. А тут нету никакого оператора сравнения....

Что означает конструкция #if 0 - C (СИ)
есть у меня готовая программа. в ней есть следующая конструкция #if 0 //опреаторы #else //операторы #endif хотел бы...

Что означает условие if(!in) - C (СИ)
Здравствуйте, что означает if(!in), что это за условие?

Что означает строка? - C (СИ)
Объясните пожалуйста словами, что значит строка int *(*table());

Что означает операция *= - C (СИ)
Что означает данное выражение в Си? number *= 10;

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
likehood
657 / 538 / 176
Регистрация: 25.12.2016
Сообщений: 1,755
Завершенные тесты: 3
08.01.2017, 08:49 #2
Адрес переменной pbuf приводится к типу "указатель на uint8_t", после чего значение по этому адресу записывается в переменную memtype (с неявным преобразованием к типу uint8_t). Иными словами, в memtype заносится адрес переменной, на которую указывает pbuf. Смысл этой конструкции для меня остаётся загадкой.

Добавлено через 9 часов 9 минут
Ещё важно отметить, что преобразование указателя к типу uint8_t происходит с потерей старших байтов, поскольку тип uint8_t - восьмибитный, и адрес в него никак не влезет. Поэтому остаётся неясным, зачем вообще может понадобится такая конструкция.
2
Fulcrum_013
718 / 743 / 73
Регистрация: 14.12.2014
Сообщений: 5,840
Завершенные тесты: 3
08.01.2017, 09:41 #3
Цитата Сообщение от likehood Посмотреть сообщение
Поэтому остаётся неясным, зачем вообще может понадобится такая конструкция.
К примеру затем чтобы поиметь младшие 8 разрядов адреса. Если это выдрано из какого нибудь менеджера кучи то может быть очень даже актуальной для решения общей задачи операцией.
1
likehood
657 / 538 / 176
Регистрация: 25.12.2016
Сообщений: 1,755
Завершенные тесты: 3
08.01.2017, 10:11 #4
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
К примеру затем чтобы поиметь младшие 8 разрядов адреса.
В принципе, из кода это понятно. Но, чтобы у читателя не возникало сомнений, я бы назвал переменную memtype как-то по другому. Например, address_low_byte. Тем самым подчеркнув, что мы понимаем, что делаем, и нам действительно нужен только младший байт.
0
Fulcrum_013
718 / 743 / 73
Регистрация: 14.12.2014
Сообщений: 5,840
Завершенные тесты: 3
08.01.2017, 11:04 #5
Цитата Сообщение от likehood Посмотреть сообщение
Тем самым подчеркнув, что мы понимаем, что делаем, и нам действительно нужен только младший байт.
Не факт что он младший. Это платформозависимо. Может быть как раз и старшим который в данной реализации менеджера кучи определяет тип памяти куда указывает указатель (стек/сегмент данных/сегмент кода/куча/common область и т.п.).
2
likehood
657 / 538 / 176
Регистрация: 25.12.2016
Сообщений: 1,755
Завершенные тесты: 3
08.01.2017, 12:04 #6
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Не факт что он младший.
Странно, мне казалось, что преобразование типов выполняется вполне однозначным образом. Другое дело, что адрес может по разному храниться в переменной-указателе. Но само преобразование одного целого числа в другое, меньшее по размеру, разве зависит от платформы?
0
Fulcrum_013
718 / 743 / 73
Регистрация: 14.12.2014
Сообщений: 5,840
Завершенные тесты: 3
08.01.2017, 12:25 #7
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от likehood Посмотреть сообщение
Другое дело, что адрес может по разному храниться в переменной-указателе.
Вот правильно тут как раз и берут первый байт адреса. т.е. к uint8_t* приводят не сам buf а &buf - т.е. адрес указателя. а потом по этому адресу берут первый байт.

Добавлено через 10 минут
т.е.&buf приводят к типу uint8_t* а потом извлекают значение по этому указателю. поскольку указатель имеет тип uint8_t* то и извлекается один байт который уже ни к чему не приводится при присваивании.
2
likehood
657 / 538 / 176
Регистрация: 25.12.2016
Сообщений: 1,755
Завершенные тесты: 3
08.01.2017, 12:28 #8
Да, теперь понял. Спасибо.
0
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
08.01.2017, 12:38 #9
Цитата Сообщение от likehood Посмотреть сообщение
Странно, мне казалось, что преобразование типов выполняется вполне однозначным образом
В том-то и дело, что тут нет преобразования типов. Преобразование типов работает над значениями, в то время, как ты хочешь получить сначала битовый образ значения, а потом выковырять из него нужный набор битов и уже их превратить в значение нужного типа

Смысл конкретно данного примера мне так же непонятен. Если это фрагмент какого-то менеджера памяти, то логика его работы будет различаться на big-endian и little-endian
1
zer0mail
2334 / 1960 / 192
Регистрация: 03.07.2012
Сообщений: 7,029
Записей в блоге: 1
08.01.2017, 14:24 #10
Не пойму, чем memtype = *(uint8_t*)(&pbuf); отличается от memtype = *pbuf;
0
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
08.01.2017, 15:26 #11
Цитата Сообщение от zer0mail Посмотреть сообщение
Не пойму, чем memtype = *(uint8_t*)(&pbuf); отличается от memtype = *pbuf;
Если бы было написано "memtype = *(uint8_t*) pbuf;", то ничем. Но тут стоит &pbuff
1
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
08.01.2017, 17:39  [ТС] #12
Всем огромное спасибо за участие!
Я могу привести весь код функции (это из готового официального примера от производителя), там потом полученное значение сравнивается с магическими (для меня) константами и pbuf приводится к data, xdata или pdata. и выполняется действие по макросу
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
uint16_t hal_nrf_read_multibyte_reg(uint8_t reg, uint8_t *pbuf)
{
  uint8_t ctr, length;
  uint8_t memtype;
  uint8_t read_byte; /*lint -esym(530,read_byte) symbol not initialized*/
  bool first_round;
  first_round = true;
 
  memtype = *(uint8_t*)(&pbuf);
 
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = ctr = hal_nrf_get_address_width();
      CSN_LOW();
      hal_nrf_rw(RX_ADDR_P0 + reg);
      break;
 
    case HAL_NRF_RX_PLOAD:
      reg = hal_nrf_get_rx_data_source();
      if (reg < 7U)
      {
        length = ctr = hal_nrf_read_rx_payload_width();
        CSN_LOW();
        hal_nrf_rw(R_RX_PAYLOAD);
      }
      else
      {
        ctr = length = 0U;
      }
      break;
 
    default:
      ctr = length = 0U;
      break;
  }
 
  if (memtype == 0x00U)
  {
    uint8_t data *buf = (uint8_t data *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else if (memtype == 0x01U)
  {
    uint8_t xdata *buf = (uint8_t xdata *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else if (memtype == 0xFEU)
  {
    uint8_t pdata *buf = (uint8_t pdata *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else
  {
    uint8_t *buf = (uint8_t *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
 
  CSN_HIGH();
 
  return (((uint16_t) reg << 8) | length);
}
0
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
08.01.2017, 17:52 #13
Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
Я могу привести весь код функции
Без описания используемых в нём макросов он малополезен
Кому интересен оригинал, видимо, следует заглянуть сюда https://github.com/elechouse/Wireles.../src/hal_nrf.c
0
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
08.01.2017, 18:07  [ТС] #14
Цитата Сообщение от Evg Посмотреть сообщение
Без описания используемых в нём макросов он малополезен
Ну почему же, макросы к теме не относятся, а будут отвлекать внимание. К тому же, если вы обратили внимание, они одинаковы в каждом случае при сравнении значения memtype с магическими (для меня) значениями. Вопрос был про выражение.
Это код из программного обеспечения к комплекту разработчика от производителя чипа. Скачивается на официальном сайте (без гитхаба). чип nRF24LE1.
0
Evg
Эксперт CАвтор FAQ
17808 / 6014 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
08.01.2017, 18:51 #15
Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
К тому же, если вы обратили внимание, они одинаковы в каждом случае
Это они для тебя, как для начинающего одинаковы. Я, например, более чем уверен, что макрос NRF_READ_MULTIBYTE_REG_COMMON_BODY раскрывается во что-то, что использует переменную "buf", которая имеет разный тип в каждом из блоков. Причём даже не понятно, что за тип, потому что по внешнему виду имеет место быть синтаксическая ошибка, так что либо uint8_t, либо data/xdata/pdata являются макросами. Либо какое-то нестандартное расширение Си в компиляторе под этот девайс

Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
Вопрос был про выражение
Для тебя вопрос по языку исчерпан, хотя лично я более чем уверен в том, что ты не понимаешь, что конкретно этот код делает. Так же как и прочие не понимают, ради чего в код включена такая извращённая конструкция. Наверняка найдётся и те, кому станет интересно, что же там такое, бесприменительно к тому, поймёшь ты это, или нет. Собственно, для них и поместил ссылку
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2017, 18:51
Привет! Вот еще темы с ответами:

Что означает запись .5? - C (СИ)
Что означает .5 на C? Спасибо :) Потрудитесь хотя бы одну строку набрать текстом, а не выкладывать в виде картинки!

Что означает символ $? - C (СИ)
Привет. Столкнулся с таким кодом: var i=0; while($i&lt;100) { //операторы I++; }

Что означает каждая строка? - C (СИ)
Помогите, пожалуйста. Что обозначает каждая строка? Вот готовый рабочий код, который подсчитывает количество букв в самом длинном слове и...

Что означает знак * в коде - C (СИ)
Вот функция из программы int length(char* st) { int L = 0; char* p = st; while (*p++) L++; return(1);...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.01.2017, 18:51
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru