«Указатель / ссылка» на массив, кажется, указывает на некоторые проблемы в понимании того, как работают указатели по отношению к массивам.
Когда вы берете указатель на элемент массива и «передаете массив» для такой функции вы запускаете затухание массива в указатель, и в итоге вы передаете указатель на первый элемент.
#include <iostream>
void f(int* p) {
std::cout << p << '\n';
}
int main() {
int arr[5];
// both are exactly the same
f(arr);
f(&arr[0]);
}
Таким образом, в вашем случае, передача sensors
через sensor*
будет работать, и вы сможете изменить содержимое массива:
#include <iostream>
#include <algorithm>
void set(int val, int ix, int* storage) {
storage[ix] = val;
}
int main() {
int values[10];
std::fill(std::begin(values), std::end(values), 0);
set(42, 3, values);
for (auto v : values) {
std::cout << v << '\n';
}
}
При этом, если вы передаете массив, вам нужно каким-то образом оценить размер, чтобы избежать заграничный доступ; Один из способов сделать это - передать его в качестве другого параметра.
При этом гораздо предпочтительнее использовать std::array
, который затем можно передать в качестве ссылки. Таким образом, вы избегаете всех указателей и получаете размер, передаваемый автоматически. Недостатком является то, что вам нужно знать размер во время компиляции.
К сожалению, при предоставлении std::string_view
в C ++ отсутствует встроенный примитив для просмотра памяти. std::vector
используется в настольном коде, но его использование во встроенной программе для ограниченного MCU довольно сомнительно. В этом случае вам может понадобиться / вы хотите написать собственный тип, включающий указатель и размер, например:
template<typename T>
struct ArrayView {
T* ptr;
std::size_t sz;
public:
template<int arrSize>
ArrayView(T (&arr)[arrSize]) : ptr(arr), sz(arrSize) { }
T& operator[](int i) { return ptr[i]; }
std::size_t size() const { return sz; }
};