将程序返回到预触发状态

时间:2013-03-27 15:20:33

标签: 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,将程序返回到其原始的预警状态?

1 个答案:

答案 0 :(得分:1)

我认为,通过思考程序的流程,你会从中受益匪浅。现在,我可以推断出你的程序流程:

  • 您有一个外循环,用于检查至少一个通道ID上的温度。在该循环中,您有第一次向我们展示的if声明。
  • 然后激活闹钟执行其他一些操作,但循环直到温度下降,调用logSubsystem
  • logSubsystem然后可能会获得某种用户输入,并且从那里开始,你希望它调用你的初始函数,大概称为准备限制。

这个问题是这些功能都没有完成。他们都互相打电话,你最终会得到一个堆栈溢出。很好,因为这是这个网站的名称,但不是你想要的东西。

你基本上需要的是状态机。您需要能够跟踪值,查看这些值以及调用对这些值进行操作的返回的函数。应该只有一个循环,它应该根据这些值的所有内容控制所发生的事情。好消息是,你已经掌握了所有这些。 temperatureChannel正在跟踪你的值,并且你有while循环a-plenty。

让我向你提出我建议你的计划应该如何流动的建议:

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]内,告知警报是否响铃,在activateAlarm中将其设置为true,然后根据checkTemperatureValuesOutOfRange的返回值将其重置为false。
  • 不是让自己留在activateAlarm / logSubsystem区域,而是每次都返回,每次检查你的值,看看你是否还在那里。这是关键点 - 您的功能应该很快,而不是垄断您的处理器。让每个函数只执行一种操作,并使所有控件都来自主循环。

我对你的代码进行了很多更改,我不知道你是否被允许制作所有这些代码,但是你需要类似的东西。它更加强大,为您提供了四处成长的空间。