2013-03-27 61 views
0

首先這個被觸發:返回程序預觸發狀態

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遞減並獲取當前溫度t o低於極限(< 100,或> 50),那麼它將返回到compareLimit函數,並且對上限/下限觸發狀態的要求將爲FALSE,將程序返回到其原始的預警狀態?

+1

沒有足夠的上下文。根據你的問題,你可能需要:1.一個'while'循環,2.'longjmp()',3。 – 2013-03-27 15:22:07

+0

我還能告訴你什麼?我只是不想給你帶來不必要的代碼 – 2013-03-27 15:26:34

+0

這也沒關係。特別是,我會很喜歡'activateAlarm()'函數。 – 2013-03-27 15:27:36

回答

1

我想你會從很多關於你的程序如何流動的問題中受益頗多。現在,我可以推斷出你的程序流程是:

  • 你有一個外循環,檢查溫度,在至少一個通道ID。在那個循環中,你有第一次給我們看的if聲明。
  • 然後激活報警做一些其他的東西,但循環,直到溫度下降,呼籲logSubsystem
  • logSubsystem然後可能會得到某種用戶輸入,並從那裏,你想它調用你的初始函數,可能被稱爲準備限制。

問題是這些功能都沒有完成。他們都會互相調用,最終會導致堆棧溢出。很好,因爲這是這個網站的名字,但不是你想要的東西。

你基本上需要的是一臺狀態機。你需要一些跟蹤值的東西,看看這些值,並調用返回的函數,這些函數對這些值進行操作。應該只有一個循環,並且它應該根據這些值發生什麼來控制所發生的情況。好消息是,你已經擁有了所有這些。 temperatureChannel正在跟蹤你的價值,並且你有很多循環。

讓我給你我的方式建議,我建議你的程序應該流向:

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區域,而是每次都會返回,並且每次檢查您的值以查看是否仍然存在。這是關鍵 - 你的功能應該很快,而不是壟斷你的處理器。讓每個函數只做一種事情,並讓所有的控制來自主循環。

我對你的代碼做了很多改變,我不知道你是否被允許創建所有的代碼,但是你需要類似的東西。它更加強大,併爲您提供四處擴展的空間。

+0

斯科特...非常感謝你的深思熟慮的迴應......我不知道這種情況是堆棧溢出,但這是我學到的東西:)然而,我在想,我需要停止callng函數之後功能,並專注於從我的主和其他任何地方調用它們。非常感謝您的回覆... – 2013-03-27 20:20:53

+0

沒問題。每次添加函數時,都會將它推送到函數堆棧中。這是分配所有包含可執行語句的內存和包含本地變量的所有內存的地方。 (當你退出函數時,它會彈出堆棧。)每個操作系統都有一定的限制,你可以放在堆棧上(這可能是「所有可用的內存」)。特別是在一個看起來像是要永遠存在的系統中,不斷添加函數最終會讓你溢出這個限制。 – 2013-03-27 21:05:16