DEV Community

codemee
codemee

Posted on • Updated on

C/C++ 的條件判斷

許多人可能都是看網路上的範例自學 Arduino, 因此對於程式語言本身沒有太多的研究, 反正跑起來是對的就好了, 這就導致學了一陣子後, 常常會遇到困惑, 像是以下這個例子:

void setup() {
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

void loop() {
  if(digitalRead(2))
    digitalWrite(13, HIGH);
  else
    digitalWrite(13, LOW);
}
Enter fullscreen mode Exit fullscreen mode

就會有初學者問為什麼 digitalRead() 可以直接拿來當條件判斷?條件判斷不是都要有比較關係嗎?

C 語言的 if 其實是看數字說話

如果你看 C 語言的規格書, 會看到 if 後面的小括號內要是一個運算式, 而 if 其實就是根據這個運算式的運算結果是不是 0 來決定要執行哪一段程式。只要運算結果不是 0, 就代表條件成立, 會執行 if 內的程式。

可是 digitalRead() 的傳回值是 HIGH 或 LOW, 跟是不是 0 有什麼關係呢?如果你打開安裝 Arduino 的資料夾, 在 hardware\arduino\avr\cores\arduino 下有一個 Arduino.h 檔, 在其中就可以看到 HIGH/LOW 的定義:

#define HIGH 0x1
#define LOW  0x0
Enter fullscreen mode Exit fullscreen mode

HIGH 就是 1, LOW 就是 0, 所以將 digitalRead() 直接放到 if 當條件判斷的運算式, 意思就是讀到高電位時條件成立。

比較運算子的運算結果也是 0 或 1

如果你看規格書上關於比較運算子的說明, 會看到關係運算子的運算結果不是 0 就是 1, 1 表示比較的關係成立。也正因為如此, 所以可以拿比較運算來當 if 的判斷條件, 把上述例子改寫成這樣:

void setup() {
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

void loop() {
  if(digitalRead(2) == HIGH)
    digitalWrite(13, HIGH);
  else
    digitalWrite(13, LOW);
}
Enter fullscreen mode Exit fullscreen mode

這兩種寫法效用相同, 但有實質上以及語意上的差異:

  1. 第 2 種寫法實際上多做了一個比較運算, 然後才將運算結果給 if 判斷, 所以比較本格派的程式師會堅持第 1 種寫法執行效率比較好, 而且程式比較精簡, 應該要這樣寫比較好。

  2. 第 2 種寫法在語意上比較清楚, 閱讀程式的人都會很清楚比較的條件是什麼?比較容易理解。

對於初學者, 我比較建議採用第 2 種寫法, 除非真的有必要計較細微的執行效率, 否則盡量採用清楚的寫法對初學者會是比較好的做法。

簡單的來說, C 語言是以 0不成立、否、假、錯的概念, 只要不是 0, 就是成立、是、真、對的概念。

但是 Arduino 是 C++

有人可能會說『可是 Arduino 是 C++ 語言, 跟 C 有一樣嗎?』。

沒錯, Arduino 採用的語言是 C++, 它的 if 是把條件運算式的運算結果轉成 bool 型別後, 再依據轉型結果是 true 還是 false 決定流程。而轉成 bool 型別的規則基本上就是剛剛提到 C 語言的概念, 0 會轉成 false, 其他值轉成 true。另外, C++ 的比較運算子運算結果也是 bool

因此, C 語言的寫法也適用於 C++, 不過老話一句, 我還是建議採用比較直白的方式撰寫程式, 避免誤會程式的意思。

Discussion (0)