Как Arduino справляется с передачей этого объединения?
Я не уверен, как это будет обрабатываться компилятором Arduino. Если кто объяснит что и почему, буду признателен. Это, очевидно, очень упрощено, но в нем действительно содержится реальная проблема.
На уровне модуля у меня есть этот union
. Я понимаю, что это, строго говоря, неправильный C++, но у меня он работает, по крайней мере, когда используется напрямую, а не передается в качестве аргумента функции.
union _TAT { // доступ как байты или uint32
uint32_t wide = 0;
uint8_t bytes[4];
};
_TAT oneTAT; // переменная _TAT
Предположим, у меня также есть функция, которая работает с ними:
void fix_Term(_TAT atat) {
atat.wide = 0;
atat.bytes[3] = 17;
}
... и я вызываю его с помощью:
fix_Term(oneTAT);
Насколько я понимаю, передача AnArray[]
эквивалентна передаче *AnArray
, поэтому функция может/должна видеть atat.bytes[3]
как указатель на этот байт переменной. А как насчет atat.wide
? Я не передал явно oneTAT
по ссылке, так что...?
Что здесь может произойти на самом деле? Он компилируется без нареканий, но я не могу его протестировать, потому что аппаратное обеспечение, от которого оно зависит, еще недоступно. Кроме того, даже если это сработает, я хотел бы знать почему.
И, конечно же, если это просто неправильно, как мне лучше всего выполнить передачу и изменение такой переменной?
@Jim Mack, 👍0
Обсуждение2 ответа
Лучший ответ:
В C и C++ сбивает с толку тот факт, что массивы передаются как указатели, но экземпляр класса, структуры или объединения всегда передается по значению (то есть как копия), включая массивы, которые являются частью пространства памяти структуры как в случае вашего союза.
Если вы хотите передать по ссылке, объявите параметр функции как тип ссылки. Например, void fix_Term(_TAT& atat) {
.
Спасибо, кажется, это недостающая часть для меня. Я хочу пройти по ссылке, но был сбит с толку (как вы заметили) * / [] ., @Jim Mack
Да, передача AnArray[]
эквивалентна передаче *AnArray
. Но объявление uint8_t *anarray1
не эквивалентно объявлению uint8_t anarray2[4]
в структуре/классе/объединении определение. Первый включает в себя указатель на байт в структуре, последний фактически включает в себя 4 байта в структуре. Таким образом, в последнем случае anarray2
уже указывает на данные, и использование variable.anarray2[0]
правильно дает вам значение в структуре при вызове variable. anarray1[0]
приведет к неопределенному поведению, поскольку указатель указывает куда угодно.
Итак, ваш код компилируется и выполняется без ошибок, но поскольку вы передаете объединение по значению, эффект от вашей функции fix_term
отбрасывается, как если бы вы передали обычное значение введите вместо этого (например, int).
Однако он может передать его по ссылке: void fix_Term(_TAT & atat)
+ вызов тот же, а затем он изменит исходную переменную объединения., @KIIV
@KIIV Конечно, но я думаю, что вопрос был о существующем коде., @PMF
Да, вопрос был о том, что делает исходный код, но он также требовал совета, как заставить его работать. Я думаю, теперь понял, благодаря вам и Юраю., @Jim Mack
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Как работать с аналоговыми контактами в цикле?
- Какие есть другие IDE для Arduino?
- Как использовать переменные и функции в нескольких файлах .ino
- Разница между void setup() и void setup(void)
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
вы можете протестировать свой собственный код в симуляторе Arduino от tinkercad. Arduino обычно примерно такой же, как простой C++, поэтому проводник компилятора — еще один онлайн-вариант., @dandavis