Лишний значок в коде?

junior_developer
Offline
Зарегистрирован: 27.11.2017

Подскажите пожалуйста, зачем в этой строчке символ "&"?

radio.write(&data, sizeof(data));

Вот код целиком

#include <SPI.h>                                          // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h>                                     // Подключаем файл настроек из библиотеки RF24
#include <RF24.h>                                         // Подключаем библиотеку для работы с nRF24L01+
RF24           radio(9, 10);                              // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
int            data[2];                                   // Создаём массив для приёма данных
void setup(){
    radio.begin();                                        // Инициируем работу nRF24L01+
    radio.setChannel(5);                                  // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
    radio.setDataRate     (RF24_1MBPS);                   // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
    radio.setPALevel      (RF24_PA_HIGH);                 // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
    radio.openWritingPipe (0x1234567890LL);               // Открываем трубу с идентификатором 0x1234567890 для передачи данных (на одном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
}
void loop(){
    data[0] = analogRead(A1);                             // считываем показания Trema слайдера с вывода A1 и записываем их в 0 элемент массива data
    data[1] = analogRead(A2);                             // считываем показания Trema потенциометра с вывода A2 и записываем их в 1 элемент массива data
    radio.write(&data, sizeof(data));                     // отправляем данные из массива data указывая сколько байт массива мы хотим отправить. Отправить данные можно с проверкой их доставки: if( radio.write(&data, sizeof(data)) ){данные приняты приёмником;}else{данные не приняты приёмником;}
}

И нужен ли он там вообще?
Если да, то объясните пожалуйста, кто знает, что означает этот символ? Заранее спасибо всем ответившим!

b707
Offline
Зарегистрирован: 26.05.2017

data и &data - это разные вещи

data - это переменная

&data - адрес переменной data в памяти контроллера

Если в функцию передается адрес, убрать "&" нельзя

 

sadman41
Offline
Зарегистрирован: 19.10.2016
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

junior_developer пишет:

Подскажите пожалуйста, зачем в этой строчке символ "&"?

Это "Лишний значок в коде" - не берите в голову.

junior_developer
Offline
Зарегистрирован: 27.11.2017

Дело в том, что в этом примере data - это массив, а не одна переменная!

int            data[2]; 

Поэтому мне непонятно, что  произойдет

radio.write(&data, sizeof(data));

Из памяти будет взят адрес начала этого массива? Верно? А sizeof (data) это для подсчета его длины?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, я же Вам говорил - лишний значок. Уберите - ничего не изменится. Попробуйте. sizeof - да, длину узнать.

b707
Offline
Зарегистрирован: 26.05.2017

junior_developer пишет:

Поэтому мне непонятно, что  произойдет

radio.write(&data, sizeof(data));

ЕвгенийП прав, в этом коде "&" - "лишний значок", тут его можно выкинуть и ничего не изменится. Но в общем случае это вещь нужная :)

 

junior_developer
Offline
Зарегистрирован: 27.11.2017

Спасибо всем ответившим! Насколько я понял, операторы & и * обычно всегда используются попарно! Простейший пример с моими комментариями!

int main(void)

{
 int target, source; // объявление переменных
 int *m;  // объявление указателя

source = 10;  // присвоить переменной "source" значение 10
m = &source; // взять адрес переменной source и поместить его в переменную "m"
target = *m; // получить значение переменной по адресу m и поместить его в "target"

printf("%d", target); // напечатать значение переменной "target" в десятичной системе счисления

return 0;
}

Если где-то ошибся, поправьте меня пожалуйста!
В  коде (см. стартовый пост). мне встретился только символ &. Поэтому я и предположил, что он лишний!
Хотя возможно и не лишний, а используется для быстрого доступа к элементам массива!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

junior_developer пишет:

Хотя возможно и не лишний, а используется для быстрого доступа к элементам массива!

Вы читаете, что Вам пишут? Или только сами пишете? Третий раз Вам говорю - лишний он там. Попробуйте, наконец убрать его и посмотреть что изменится.

sadman41
Offline
Зарегистрирован: 19.10.2016

junior_developer пишет:

В  коде (см. стартовый пост). мне встретился только символ &. Поэтому я и предположил, что он лишний!

Хотя возможно и не лишний, а используется для быстрого доступа к элементам массива!

Скорее - не для быстрого, а для экономного. Ну и быстрого, в какой-то мере.

Имя массива всегда указывает на адрес его первого элемента, поэтому в данном конкретном случае нет разницы - с & или без. Но если бы вы захотели отправить, к примеру, вторую половину массива из 20 символов, то можно было бы написать: &data[10] безо всяких промежуточных копирований в другой массив, как это непременно бы пришло в голову.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:
всегда указывает на адрес его первого элемента
Нулевого.

junior_developer
Offline
Зарегистрирован: 27.11.2017

Да, действительно! Нумерация в массиве начинается с нуля, а не с единицы, поэтому первый элемент будет иметь индекс 0 (ноль)!

 &data[10]  - это адрес 11 элемента массива и если он из двадцати символов, то 11 это как раз и начало половины!

Первая половина имеет индексы [0] - [9]. а вторая [10] - [19].  Верно?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

junior_developer пишет:

 &data[10]  - это адрес 11 элемента массива и если он из двадцати символов, то 11 это как раз и начало половины!

В общем и целом - да, но выражение &data[10] выглядит излише вычурным и имеет смысл только если одна из операций & или [] переопределена  (или обе сразу).

Для обычного массива гораздо проще запись data + 10 - тоже самое, что и &data[10]. Если что, не забывайте только в скобки брать, а то у плюса приоритет невелик.

sadman41
Offline
Зарегистрирован: 19.10.2016

Адреса элементов массива я считаю с нуля, а сами элементы с единицы - я же человек ;)

Долго думал - как мне проиллюстрировать половину массива - может даже через (sizeof(data)/2), но решил на простых числах. А так - вычисляйте половину, как понравится, хоть через битовый сдвиг.

И по мне так запись &data[10] более понятна, чем data + 10, где еще непонятно в куске кода, что есть data - массив или простой int.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 Выражение  data[10]  , *(&data[10])  и *(data+10) одно и тоже.  ;)