繁体   English   中英

在C ++中循环数组时访问struct属性

[英]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]的副本将保持不变。

选项1

丢弃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];

选项2

使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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM