在函数中切换case语句不会切换C ++

时间:2019-12-24 00:27:20

标签: c++ arduino switch-statement

我试图在两个不同的函数中使用两个switch case语句来通过串行软件包控制微控制器,但是其中一个函数不会切换并且程序会无限期地循环。其中一个功能根据enum进行切换:

enum class State {

 example_a,
 example_b,
 example_c

};

void serialTask(State stateArg, ObjectA exampleA, ObjectB exampleB, ObjectC exampleC, ObjectD exampleD) {
  switch (stateArg) {
    case State::example_a:
      Serial.println("Serial Task, example a");
      exampleA.doSomething();
      stateArg = State::example_a;
      break;

    case State::example_b:
      Serial.println("Serial Task, example b");
      exampleB.doSomething();
      stateArg = State::example_b;
      break;

    case State::example_c:
      Serial.println("Serial Task, example c");
      exampleC.doSomething();
      stateArg = State::example_c;
      break;
   }
};

我将所有其他对象都作为参数,因为我会根据情况调用它们的函数或修改其成员。

另一个功能根据串行端口切换enum的值:

void stateSwitch(State stateArg) {
    if (Serial.available()) {
        uint8_t code = Serial.read();
        switch (code) {
        case 'a':
            stateArg = State::example_a;
            break;
        case 'b':
            stateArg = State::example_b;
            break;
        case 'c':
            stateArg = State::example_c;
            break;
   }
};

后来他们在我的main.cpp中被打来电话,

ObjectA aObj;
ObjectB bObj;
ObjectC cObj;
ObjectD dObj;
volatile State stateObj;

void setup(){

stateObj = State::example_a;
Serial.begin(115200);


};

void loop(){

stateSwitch(stateObj);
serialTask(stateObj, aObj, bObj, cObj, dObj);

};

这是问题的简化版本,但可以说明问题所在。该程序可以编译,但是由于某种原因它不能跳出State::example_a。我正在将Teensy微控制器与PlatformIO(Visual Studio的扩展)中的Arduino框架配合使用。谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您正在按值将stateSwitch传递给foreach (var json in myweather.list.Take(n))

这意味着正在制作副本,并且您正在修改副本;不是原始的。

答案 1 :(得分:1)

void serialTask(State stateArg, ...
    stateArg = State::example_a; // affects local copy only

这是按值传递的,因此为该函数创建了一个副本。它不会将任何更改回显到原始变量。

为此,您需要通过引用将其传递:

void serialTask(State &stateArg, ...
    stateArg = State::example_a; // affects variable used in call

请注意,您需要在所有要更改变量的函数中进行引用传递(因此stateSwitchserialTask)。

通过示例,请注意以下几点:

#include <iostream>
void procA(int num) {
    num = 7;
}
void procB(int &num) {
    num = 42;
}
int main() {
    int num = 1; std::cout << num << '\n';
    procA(num);  std::cout << num << '\n';
    procB(num);  std::cout << num << '\n';
}

这将导致三行1142,因为对procA的调用是按值传递的,不会影响传递的变量,只是它的本地副本。

另一方面,procB作为引用传递,确实更改了传递的变量。

还请注意,无论您是通过值传递还是引用传递,调用都是相似的。您无需以任何方式更改呼叫。


也许还想研究这些事情背后的逻辑:

case State::example_a:  // current state
      Serial.println("Serial Task, example a");
      exampleA.doSomething();
      stateArg = State::example_a; // why set to same/original state?
      break;

状态机将状态强制返回执行事件之前的值是非常不寻常的。 可以,因为我们看不到您的所有代码,但是我要小心一点。