c - 将程序返回到预触发状态

标签 c function operators

首先会触发:

if ((temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) | (temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit))
     activateAlarm(channelID);

激活警报被触发,然后从那里:

void activateAlarm(int channelID);   
{  while (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit || temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit)
   {    
    logSubsystem(temperatureChannel[channelID].currentTemperature); 
   }    
}

然后,以下情况会触发警报屏幕:

int logSubsystem(int currentTemperature)

case 'F': //if user input is 'F'
case 'f': //if user input is 'f'        

            currentTemperature--;
            printf("your current exceeded temp is %i\n \n", currentTemperature);    
            if (currentTemperature <= 100 || currentTemperature >= 50);
                  compareLimit();
                break; //exits loop

如何设置此函数,以便如果用户用 F 递减并使当前温度低于限制(<100 或 >50),那么它将返回到 CompareLimit 函数以及对上限/下限触发状态将为FALSE,将程序返回到原来的报警前状态?

最佳答案

我认为,深入思考程序的流程会让您受益匪浅。现在,我可以推断出你的程序流程是:

  • 您有一个外部循环来检查至少一个 channel ID 上的温度。在该循环内,您有首先向我们展示的 if 语句。
  • 然后激活警报执行一些其他操作,但循环直到温度下降,调用logSubsystem
  • 然后 logSubsystem 可能会获取某种用户输入,然后您希望它调用您的初始函数,可能称为准备限制。

问题是这些功能都没有完成。它们都会互相调用,最终会出现堆栈溢出。很好,因为这是该网站的名称,但不是您想要的。

您基本上需要的是一个状态机。您需要一些东西来跟踪值、查看这些值并调用对这些值进行操作的返回函数。应该只有一个循环,并且它应该根据这些值对发生的情况进行所有控制。好消息是,您已经准备好了所有这些。 TemperatureChannel 正在为您跟踪这些值,并且您有大量的 while 循环。

让我给你我建议你的程序应该如何流动的建议:

bool checkTemperatureValuesOutOfRange(int channelID) {
    // this is just a convenience, to make the state machine flow easier.
    return (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) || // note the || not just one |
           (temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit);
} 

void actOnUserInput() {
    char input = // ... something that gets a user input.  It should check if any is available, otherwise return.
    switch (input) {
        case 'F':
        case 'f':
             temperatureChannel[channelID].currentTemperature--;
             break; // This doesn't exit the loop - it gets you out of the switch statement
}

void activateAlarm(int channelID) {
    // presumably this does something other than call logSubsystem?
    // if that's all it does, just call it directly
    // note - no loop here
    logSubsystem(channelID); 
}

void logSubsystem(int channelID) { // Not the current temperature - that's a local value, and you want to set the observed value
    // I really think actOnUserInput should be (an early) part of the while loop below.
    // It's just another input for the state machine, but I'll leave it here per your design
    // Presumably actually logs things, too, otherwise it's an unnecessary function
    actOnUserInput();
}

while (TRUE) { // this is the main loop of your function, and shouldn't exit unless the program does
    // do anything else you need to - check other stuff
    // maybe have a for loop going through different channelIDs?
    if (checkTemperatureValuesOutOfRange(channelID)) {
         activateAlarm(channelId);
    // do anything else you need to
}

我确信您可以看到您的代码和我的代码之间有很多差异。以下是需要考虑的一些关键事项:

  • 所有函数现在都返回。主 while 循环调用检查状态的函数,并调用更改状态的函数。
  • 我强烈建议将用户输入作为主 while 循环的一部分进行操作。它只是状态机的另一个输入。获取它,采取行动,然后检查您的状态。您可能需要从用户那里获得一些输入,否则您一开始就不会处于糟糕的状态。
  • 现在,每次都会触发警报。使用您展示的代码,这很好 - 因为 logSubsystem 就是被调用的所有内容。如果您只想让闹钟响一次,请在 temperatureChannel[channelId] 中保留一个 bool 跟踪器,用于指示闹钟是否响铃,在 activateAlarm 中将其设置为 true,然后根据 checkTemperatureValuesOutOfRange 的返回值将其重置为 false。
  • 您不是将自己留在 activateAlarm/logSubsystem 区域,而是每次都返回并检查您的值,看看您是否仍然在那里。这是关键点 - 你的函数应该很快,而不是垄断你的处理器。让每个函数只做一种事情,并且所有控制都来自主循环。

我对您的代码做了很多更改,我不知道是否允许您进行所有更改,但您需要与此类似的内容。它更加强大,并为您提供全面成长的空间。

关于c - 将程序返回到预触发状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15662533/

相关文章:

c - 使用 openmp 看不到任何加速

Javascript 调用类函数

java - Java 中是否可以有一个不使用关系运算符的 if 语句?

c++ - std::function 的 operator== 的真正目的是什么?

无法在链表中存储元素

c - libcURL CURLOPT_SSLKEYTYPE

c - 时间复杂度有何不同?

javascript - 任何使 JavaScript 比较始终为真的值?

C使用管道与 parent 沟通 child

ios - Swift 中的事件指示器