[英]Access to struct property while looping array in C++
我发生了遍历结构数组的问题。
我有这个结构:
struct sensor
{
float data = 0;
bool status = false;
Idx idx; //enum
SensorType type; //enum
};
它包含一些用于我的arduino的传感器。
因此,要发送数据,我想从它们那里接收数据,我想循环使用传感器阵列。
这是我的数组定义:
sensor sensors[] = {light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut};
最后,我想遍历此数组并调用一些方法,但是当我尝试通过索引访问任何传感器时,所有属性的值都为零。
for (unsigned int i = 0; i < sizeof(sensors) / sizeof(sensor); i++)
{
Serial.print("type:");
Serial.print(sensors[i].type);
Serial.print(" sens.idx:");
Serial.print(sensors[i].idx);
Serial.print(" sens.data:");
Serial.print(sensors[i].data);
Serial.print(" sens.status:");
Serial.print(sensors[i].status);
Serial.println();
}
在此循环中,我得到如下输出:
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
但是,当我直接访问任何结构时,例如:
Serial.print("type:");
Serial.print(pressure.type);
Serial.print(" pressure.idx:");
Serial.print(pressure.idx);
Serial.print(" pressure.data:");
Serial.print(pressure.data);
Serial.print(" sens.status:");
Serial.print(pressure.status);
Serial.println();
我得到:
type:3 pressure.idx:13 pressure.data:0.00 sens.status:1
定义了light
并将其保留为默认值。
sensor sensors[] = {light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut};
将light
复制到sensors[0]
。 这意味着sensors[0]
包含相同的数据作为light
,但是不一样的东西作为light
。 稍后,当代码为light
分配值时, sensors[0]
的副本将保持不变。
丢弃light
朋友。 添加为传感器命名的枚举类型
enum sensor_names
{
LIGHT, // will be 0
PRESSURE, //will be 1
...
NR_SENSORS // must be last. Used to size the array and for loop terminators
};
并使sensors
成为正确尺寸的简单阵列
sensor sensors[NR_SENSORS];
如果可用,请随时使用std::array
和现代C ++的更智能enum
。 我对Arduino可用和不可用的东西一无所知,因此我坚持使用基本的C样式数组和enum
。 如果您有更好的工具,请使用它们。
然后访问light
作为sensors[LIGHT];
使sensors
存储指针并相应地更改访问。
sensor * sensors[] = {&light, &pressure, .... };
我更喜欢第一种选择。 没有重复,并且将项目放置在数组中错误位置的机会较小,因此有所不同。
创建结构数组时:
sensor sensors[] = {light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut};
这将为您用来创建列表的每个结构创建一个副本 。 您要么必须使用一个指针数组:
sensor* sensors[] = {&light, &pressure, &pressureHpa, &temperature, &humidity, &temperatureOut, &humidityOut};
或者,您必须创建自己的类,该类存储对它们的引用:
class SensorArray {
sensor** arr = nullptr;
size_t count = 0;
public:
size_t size() const {
return count;
}
// Default-construct it
SensorArray() = default;
// Make a copy of the SensorArray
SensorArray(SensorArray const& source)
: arr(new sensor*[source.size()])
, count(source.size())
{
std::copy_n(source.arr, source.count, arr);
}
// Move-construct SensorArray
SensorArray(SensorArray&& source)
: arr(source.arr)
, count(source.count)
{
source.arr = nullptr;
source.count = 0;
}
template<class T...>
SensorArray(T&... sensors)
: arr(new sensor*[] { &sensors... }) // Initialize arr
, count(sizeof...(sensors)) // Initialize count
{} // Constructor is empty because we already initialized stuff
SensorArray& operator=(SensorArray const& source) {
if(this == &source) return *this;
SensorArray s = source;
swap(s);
return *this;
}
// Copy-and-swap idiom
// This automatically handles the case of self-assignment
SensorArray& operator=(SensorArray&& source) {
SensorArray s = std::move(source);
swap(s);
return *this;
}
sensor& operator[](int index) const {
return *arr[index];
}
~SensorArray() {
delete[] arr;
}
void swap(SensorArray& other) {
std::swap(arr, other.arr);
std::swap(count, other.count);
}
};
该类将按您的代码预期的那样工作,因为它将存储对每个传感器的引用 ,而不是副本:
SensorArray sensors { light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut };
// sensors will update correctly
for (unsigned int i = 0; i < sensors.size(); i++)
{
Serial.print("type:");
Serial.print(sensors[i].type);
Serial.print(" sens.idx:");
Serial.print(sensors[i].idx);
Serial.print(" sens.data:");
Serial.print(sensors[i].data);
Serial.print(" sens.status:");
Serial.print(sensors[i].status);
Serial.println();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.