无法更改存储在二维数组中的结构成员

时间:2016-01-12 08:10:46

标签: c++ arduino

我有一个包含许多结构的全局二维数组。从函数内部我尝试改变它的成员:

struct ControlPin {
    int pin;
    int previousValue;
};

ControlPin controls[CHANNELS][MULTIPLEXERS];

void readControlInput(int channel, int multiplexer) {
    ControlPin control = controls[channel][multiplexer];
    control.previousValue = analogRead(control.pin);
}

如果我在readControlInput()中打印出control.previousValue,我可以验证它是否已经更改,但是在退出函数范围后,更改就消失了。如何获取对结构的引用而不是复制它?我认为这就是发生的事情,但我不明白为什么。我知道当你将一个值作为参数传递给一个函数时,它实际上是一个副本,但是我在这里直接访问全局数组?

我已经习惯了Java,所以这对我来说有点混乱。

2 个答案:

答案 0 :(得分:4)

在Java中,所有对象都是(IIRC)引用。在C ++中,默认情况下对象是。当你这样做

ControlPin control = controls[channel][multiplexer];

复制 controls[channel][multiplexer]中的“值”,然后修改control时只修改本地值,而不是数组中的值。

最简单的选择是在声明变量时使用&符号(control)明确表示&是引用:

ControlPin& control = controls[channel][multiplexer];
//        ^
//        |
// Note ampersand here

告诉编译器control引用,然后将其初始化为引用controls[channel][multiplexer]处的对象(值)。

在不相关的情况下,C ++没有边界检查。如果您访问数组超出范围,编译器将很乐意允许它,但它将在运行时导致未定义的行为。如果你想避免奇怪的问题,你需要自己做边界检查。它不一定在函数中,但它需要在某个地方完成。

答案 1 :(得分:1)

你没有直接访问数组,这就像你将元素传递给函数一样:

void readInput(ControlPin control)
{
     control.previousValue = analogRead(control.pin);   
}

void readControlInput(int channel, int multiplexer) {
    readInput(controls[channel][multiplexer]);
}

您可以从类型中了解 - ControlPin表示相同的事情,无论它是局部变量还是参数。

在C ++中,包含类实例的变量总是包含类实例而不是它们的某种“引用”,所以就像调用函数一样,

ControlPin control = controls[channel][multiplexer];

创建数组元素的副本,并

control.previousValue = analogRead(control.pin);

修改该副本。

最简单的解决方法是将其写在一行:

controls[channel][multiplexer].previousValue = analogRead(control.pin);

您还可以使用引用变量(与Java的“引用”不同)来引用数组元素本身:

ControlPin& control = controls[channel][multiplexer];
control.previousValue = analogRead(control.pin);

如果您需要使用相同的元素执行多个操作,这将非常有用 - 与重复索引相比,它更易读,更容易出错。