2012-07-19 48 views
1

我有一個if語句[顯然]只有在條件爲真時才運行。在這個if語句之後,有一些代碼應該總是運行,之後是另一個if語句,它應該在與第一個語句相同的條件下運行。有兩個如果語句來自同一個布爾C++的最佳做法

中間的代碼使用堆棧中的特定元素執行操作,兩邊的if分別在操作前後執行堆棧上的push/pop操作。

這樣的邏輯是這樣的:

  1. 我需要推棧?是/否
  2. 在堆棧頂部執行操作
  3. 堆棧被推送了嗎? (如果是,則彈出)

項目1和3的條件相同。

這是我第一次寫這樣做在C++

#include <stdio.h> 
#include <stdlib.h> 

int somefunction(){ 
    return rand() % 3 + 1; //return a random number from 1 to 3 
} 

int ret = 0; 


//::::::::::::::::::::::::::::::::::::::: 
// Option 1 Start 
//::::::::::::::::::::::::::::::::::::::: 
int main(){ 
    bool run = (ret = somefunction()) == 1; //if the return of the function is 1 
    run = (run || (ret == 2));    //or the return of the function is 2 
    if (run){        //execute this if block 
     //conditional code 
     if (ret == 1){ 
      //more conditional code 
     } 
    } 
     //unconditional code 
    if (run){ 
     //even more conditional code 
    } 
} 
//::::::::::::::::::::::::::::::::::::::: 
// Option 1 End 
//::::::::::::::::::::::::::::::::::::::: 

寫這個我想,這可能是更有效地做到這一點後,代碼:

//::::::::::::::::::::::::::::::::::::::: 
// Option 2 Start 
//::::::::::::::::::::::::::::::::::::::: 
int main(){ 
    bool run; 
    if (run=(((ret = somefunction()) == 1)||ret == 2)){ //if the return of the function is 1 or 2 then execute this if block 
     //conditional code 
     if (ret == 1){ 
      //more conditional code 
     } 
    } 
    //unconditional code 
    if (run){ 
     //even more conditional code 
    } 
} 
//::::::::::::::::::::::::::::::::::::::: 
// Option 2 End 
//::::::::::::::::::::::::::::::::::::::: 

我更喜歡第一方法的可讀性,因爲它分成幾行,而第二行在同一行中有兩個賦值(=)和兩個比較(==)。 我想知道是否更好地使用第二種方法(出於效率或可執行文件大小的原因),或者如果有比這兩種方法更好的方法。

之前有人說它只會產生幾乎不可估量的差異,這是一個巨大的循環,必須在1/50秒內運行數千次,所以我想盡可能節省時間。

回答

5

性能不應該成爲您的擔憂:現代編譯器通常足夠聰明,可以在任何情況下優化代碼。如果代碼執行的是基本相同的事情,結果將是相同的。

所以你應該更喜歡這種更易讀的變體(因此更易於維護)。

我會寫這樣的事情:

ret = somefunction(); 
// I don't know what is the semantics of ret == 1, so let's imagine some 
bool operationIsPush = (ret == 1); 
bool operationIsOnTop = (ret == 2); 

if (operationIsPush || operationIsOnTop) 
{ 
    //conditional code 
} 

if (operationIsPush) 
{ 
    //more conditional code 
} 

//unconditional code 

if (operationIsPush || operationIsOnTop) 
{ 
    // ... 
} 
+2

+1,直到剖析器這樣說,這不是問題。 – zoul 2012-07-19 11:12:22

+0

我明白你的意思,但不一定是「如果IsPush」第一,然後「如果IsPush || IsOnTop」,然後另一個「如果IsPush」? 謝謝。 – DanJAB 2012-07-19 11:27:00

+0

@DanJAB:你是對的,我已經調整了代碼 – Vlad 2012-07-19 11:50:11

1

我相信會有在這裏的表現沒有什麼區別。第一個原因是你的編譯器可能會在每種情況下優化代碼。第二個是你只是改變操作發生的地方(比如「我做A-> B-> C或者A-> C-> B」),而不是操作的數量,所以它總是等量的計算(1個函數調用,幾個==等)。

但是認爲這個 (run=(((ret = somefunction()) == 1)||ret == 2)) 是很難看。

0

如果那裏有,你可以分割的情況 「的if-else」,以獨特的巨大的循環,它會更快

而不是

loop { if_1 {some work} if_2 {some other work} } 

可以

if_1 { loop {work }} if_2 {loop{same work}} 

更非常,如果你能分裂最內在的「如果」句子,你可以有10-20(根據你的情況)獨特的巨大循環,運行x2 x3更快(如果它緩慢,因爲「if」)

+0

這個麻煩,就是每個if_1在執行時必須有一個if_2在下一個if_1被調用之前執行(在我的情況下) – DanJAB 2012-07-19 11:24:39

+0

所以你說全部if是依賴的 – 2012-07-19 11:25:51

+0

那麼,因爲它是在一個堆棧上,循環的每一次迭代必須是這樣的:[如果]推,操作,[如果]流行,下一個......所以它不能很多「[如果]推「,然後很多操作,然後很多」[如果]彈出「 – DanJAB 2012-07-19 11:30:04

1

正確性比將兩個操作分配給一個布爾(編譯器可能會這樣做)更重要。

對於推送/彈出堆棧,您應該使用scopeguard(原始文章here)。這將確保如果某些東西拋出「無條件位」,而您確實無法確定,那麼它仍然可以正常運行。否則,你會感到有趣的驚喜(由一個堆積或溢出)。