2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Arduino】switch()文の注意点

Last updated at Posted at 2021-10-08

switch文はすっきりしたコードが書きやすく愛用していたのですが、なかなか気付きにくいエラーに遭遇したため備忘録用に。

エラー1: 内部で変数を宣言

switch文の内部で変数を宣言する際には注意が必要です。
下のプログラムでは、途中で分岐処理が止まってしまいました(写真左)。

switch_bad1.ino
//悪い例(写真左)
//switch文のみ抜粋

int i = random(3);  //0~2のランダム値(整数)

switch (i) {
  case 0:
    Serial.println("零郎");   //i=0の処理
    break;
  case 1:
    String itiro = ("一郎");  //変数を宣言!・・・・(悪い例)
    Serial.println(itiro);    //i=1の処理
    break;
  case 2:
    Serial.println("二郎");   //i=2の処理
    break;
}

変数宣言.PNG

このエラーの厄介なところは、コンパイルが通常通り完了してしまうことです。
また、変数を宣言した部分の処理(上の場合は i=1 の処理)まで実行されてしまうことも、エラーに気付きにくい要因となっています。

対処法

  • 関数に直接値を書き込む。
  • switch文の外で変数を宣言する。
  • if()while()などで入れ子にして宣言する。
switch_good1.ino
//良い例(写真右)
int i = random(3);  //0~2のランダム値(整数)

String itiro = "一郎";          //switch文の外で宣言

switch (i) {
  case 0:
    Serial.println("零郎");     //関数に直接入れる
    break;
  case 1:
    Serial.println(itiro);      //switch文の外で宣言した変数を使用
    break;
  case 2:
    if(1) {
      String ziro = "二郎";     //入れ子構造の中で宣言
      Serial.println(ziro);
    }
break;

エラー2: 同じ値を参照

caseで同じ値を参照するとエラーになります。

switch_bad2.ino
//悪い例

switch(i){
  case 0 || 1:
    Serial.println("0または1だよ");  //0か1の時の処理
    break;
  case 1:
    Serial.println("1だよ");        //1の時の処理("1"が処理被り → エラー!)
    break;
}

こちらは、Arduino IDE側でエラーを検知してくれるため、すぐに分かります。
同様の処理をするための方法は色々とありますが、無理やり"switch-case"形式で書くと可読性が悪化する可能性があるため、他の手段も模索しましょう。

switch_good2.ino
//良い例

//1.break;を除く方法(エラーの原因になりやすく非推奨)
switch(i){
  case 0:
    Serial.println("0または1だよ");  //0の時の処理(break; が無いので、そのままcase 1:へ)
  case 1:
    Serial.println("1だよ");        //1の時の処理
    break;
}

//2.case内で分岐
switch(i){
  case 0 || 1:
    Serial.println("0か1だよ");   //0か1の処理
    if(i == 1){
      Serial.println("1だよ");    //1の処理
    }
    break;
}

エラー3: String型を取り扱う

caseString(文字列型)クラスを参照するとエラーになります。

switch_bad3.ino
//悪い例

String str = "morning";

switch(str){
  case "morning":
    Serial.println("おはよう");     //str=="morning"の処理(エラー!)
    break;
  case "noon":
    Serial.println("こんにちは");   //str=="noon"の処理(エラー!)
    break;
}

こちらも、Arduino IDE側でエラーを検知してくれます
String型はchar型を発展した配列ですので、caseに単体の定数しか入れることのできないArduino IDEでは扱うことができないようです。
よって、同様の処理を行いたい場合はif()文を使用することになります。

switch_good3.ino
//良い例

String str = "morning";

if(str == "morning"){
    Serial.println("おはよう");     //str=="morning"の処理(エラー!)
}
else if(str == "noon"){
    Serial.println("こんにちは");   //str=="noon"の処理(エラー!)
}
2
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?