|
указатель на указатель, помочь разобраться |
|
|
|
Jul 27 2018, 10:48
|
Профессионал
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079
|
Встретил в коде следующую конструкцию: Код ble_advdata_tk_value_t* oob_key; err_code = nfc_tk_value_get(&oob_key); где: Код typedef struct { uint8_t tk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing TK value in little-endian format. */ } ble_advdata_tk_value_t; Код ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t ** pp_tk_value) { if (m_tag_match) { *pp_tk_value = &m_device_tk; return NRF_SUCCESS; } else { return NRF_ERROR_NOT_FOUND; } } Есть вопрос. Как все проговорить что тут происходит? Есть тип структуры ble_advdata_tk_value_t. Создали переменную- указатель на этот тип: oob_key. Дальше? Передаем не просто адрес (сам указатель oob_key), а именно адрес этого указателя? А в ф-ии уже принимаем указатель на указатель? Разыменовывали на один уровень вверх и по тому значению присвоили адрес уже массива. А проще никак? err_code = nfc_tk_value_get(oob_key); и приняли: Код ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t * pp_tk_value) { if (m_tag_match) { pp_tk_value = &m_device_tk; return NRF_SUCCESS; } else { return NRF_ERROR_NOT_FOUND; } }
|
|
|
|
|
Jul 27 2018, 12:09
|
Профессионал
Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226
|
Цитата(Метценгерштейн @ Jul 27 2018, 14:51) Хорошо, а в моем приведенном примере- в чем ошибка? Не могу указателю сразу адрес присвоить разве? Присвоить можете, только указатель ble_advdata_tk_value_t* oob_key; не изменится. P.S. Может книжечку почитать ? "Стань профи С за 24 часа"
|
|
|
|
|
Jul 27 2018, 12:39
|
Гуру
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954
|
на что будет указывать oob_key после выполнения функции в первом случае, и во втором? ну или даже так: что произойдёт с переменной pp_tk_value после выхода из функции? Цитата(Метценгерштейн @ Jul 27 2018, 19:25) Точнее, я же в их логике его и меняю через разыменование и записи по нему. pp_tk_value = &m_device_tk; где именно в данной строчке происходит разыменование указателя?
|
|
|
|
|
Jul 27 2018, 14:48
|
Знающий
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842
|
Цитата(Метценгерштейн @ Jul 27 2018, 15:54) Понимаю, что где-то не прав, но не доходит почему. Недостаток базовых знаний, вам совершенно не зря советуют книжки почитать. На уровне ассемблера при вызове функции все аргументы копируются в контекст функции. В самой функнции эти копии-аргументы можно менять как заблагорассудится, на источник своих значений они уже повлиять не могу. Поэтому и существуют указатели, что передать(скопировать) в функцию значение адреса объекта, который нужно изменить. Если бы вы программировали на с++, то вы могли бы(но делать так не стоит использовать ссылку для того что бы ваш пример заработал: Цитата ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t *& pp_tk_value) И тогда по ссылке изменения вернуться в oob_key. Но делать так, повторюсь, не надо. Нужно понять для чего нужны указатели и указатель на указатель.
|
|
|
|
|
Jul 27 2018, 15:02
|
Знающий
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842
|
Упрощенно: Переменная снаружи имеет какое-то значение Выполняется вызов В стеке аллокируется кадр под все аргументы В эти новые места копируется значения переменных (связь между аргументами в функции и теми переменными что были использованы для вызова снаружи оборвалась) В функции меняются аргументы как угодно, они находятся в том кадре что был сделан при вызове. Возврат из функции (кадр аргументов освобождается, значения которые там находились становятся мусором) Цитата(Метценгерштейн @ Jul 27 2018, 17:50) *pp_tk_value = &m_device_tk; Если ble_advdata_tk_value_t * pp_tk_value , в этом коде вы просто испортили начало массива pp_tk_value каким-то левым для содержимого этого массива адресом.
|
|
|
|
|
Jul 27 2018, 15:24
|
Профессионал
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079
|
Код ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t ** pp_tk_value) { if (m_tag_match) { *pp_tk_value = &m_device_tk; return NRF_SUCCESS; } else { return NRF_ERROR_NOT_FOUND; } } Это код из оригинального примера. Произошло разыменование указателя и записался адрес чего- то. Но, если бы на вход пришел адрес массива, то да. А посмотрите внимательно- пришел адрес адреса)) Упрощенно: Переменная снаружи имеет какое-то значение Выполняется вызов В стеке аллокируется кадр под все аргументы В эти новые места копируется значения переменных (связь между аргументами в функции и теми переменными что были использованы для вызова снаружи оборвалась) В функции меняются аргументы как угодно, они находятся в том кадре что был сделан при вызове. Возврат из функции (кадр аргументов освобождается, значения которые там находились становятся мусором)Полностью согласен. Эти вещи я знаю отлично. Это не тот вопрос, который мне не понятен. Для того и передают в ф-ю адрес переменной. Изменив ее там, она поменяется и там откуда ее переслали.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|