こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

switch の範囲指定

switch文で以下のように書いた時に処理はCを実行するのですが、
変数a が 0~9の時に こうしますよ と範囲がまだ狭い時はこのように書いても処理はできると思いますが 変数a の範囲が 0~99だった場合、いちいちcase を100回書いて(defaultを使えば処理は減るだろうけど) と数字を100回書かないといけないのはとても面倒だと思うのです。

そこで以下のようにifを使わずにswitchを使って範囲を指定する方法はありませんか?

//ifを使った場合の範囲指定
if( ( 0 <= a ) && ( a < 25 ) ){ //略 }
else if( ( 25 <= a ) && ( a < 50 ) ){ //略 }
else if( ( 50 <= a ) && ( a < 75 ) ){ //略 }
else if( ( 75 <= a ) && ( a < 100 ) ){ //略 }


//ソース
int a = 6;

switch( a ){
  case 0: case 1:
    //処理A
    break;

  case 2: case 3: case 4:
    //処理B
    break;

  case 5: case 6:
    //処理C
    break;

  case 7: case 8: case 9:
    //処理D
    break;

}

投稿日時 - 2014-01-31 17:04:48

QNo.8455236

暇なときに回答ください

質問者が選んだベストアンサー

>そこで以下のようにifを使わずにswitchを使って範囲を指定する方法はありませんか?
結論からいうとありません。

但し、今回のケース限定ですが、if文を使用したものと、同等の機能が得られるようにするとすれば、
aを25で割った商についてswitch文を使用すればよいかと。

switch(a/25){
case 0: // 0 <= a && a < 25 のケース
省略
case 1: // 25 <= a && a < 50 のケース
省略
・・・以下省略
}

投稿日時 - 2014-01-31 17:25:42

お礼

やっぱりないのですか・・。

あれば非常に便利なので皆さん使っているでしょうしね。
今回のケースは25で分けているので簡単だと思います。

本来なら0~10、10~15、15~40、40~70、70~100と言った具合にバラけて使いたかったのです。

投稿日時 - 2014-02-06 15:55:08

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

直接の回答ではありませんが、こういうロジックが必要な場合、処理A、処理B、処理Cが実は数字が少し違うだけで、実質的に同じ処理をしているというケースがよくあります。

その場合、各処理のほうを見直すと、実は、前段の分岐処理は不要になるというケースもそこそこあります。

投稿日時 - 2014-02-03 08:47:10

お礼

四則演算をしてもう少し小さな数にしたりとかですね

1の回答者様のように今回の場合は25で割れば4っつの処理をするのは簡単ですからね

投稿日時 - 2014-02-06 16:26:03

ifもswitchも使わない方法も、ここで一つ。

#include <stdio.h>
#define x5(f) f,f,f,f,f
#define x25(f) x5(f),x5(f),x5(f),x5(f),x5(f)

typedef void (*jump)(int) ;
void A(int a) { puts("処理A"); };
void B(int a) { puts("処理B"); };
void C(int a) { puts("処理C"); };
void D(int a) { puts("処理D"); };
jump cases[] = { x25(A), x25(B), x25(C), x25(D) };

int main(void)
{
 for (int i = 0; i < 100; i++) cases[i](i);
 return 0;
}

投稿日時 - 2014-02-01 05:53:11

お礼

そんな使い方もあるのですか。
これは盲点ですね。

こういう処理の仕方もあるということは覚えておきますね。

投稿日時 - 2014-02-06 16:20:38

ANo.4

switch 使う方法はいろいろ出ているので。

たとえばa が常に正だとして。
if( ( 0 <= a ) && ( a < 25 ) ){ //略 }
が成立していたら
else if( ( 25 <= a ) && ( a < 50 ) ){ //略 }
ここは通りません。
前のifが成立、ということは a<25 ですから、不成立ということは、 25<=a はかならず成立する、ということになります。
必ず成立する条件を判定するのは無駄です。

と、無駄を省くと
if( a < 0 ) { ... }
else if ( a < 25 ) { //略 }
else if ( a < 50 ) { //略 }
else if ( a < 75 ) { //略 }
else if ( a < 100 ) { //略 }
となります。ちょっと長いですが、switch~caseとそれほど変わらないと思います。

投稿日時 - 2014-01-31 21:14:17

お礼

あああ本当ですね。
すっごい省略できます。

今までは数値の範囲がわかりやすかったのであのように書いてましたが、今後はまねてみますね。

これくらいなら処理速度がそれほど変わらないのはわかるのですが、非常に大規模な処理を行いたいので処理速度に気をつけてるのですよ。

ですので、どうしてもifを使わなければいけないもの以外は、できる限りswitchを使いたいのです

投稿日時 - 2014-02-06 16:18:40

ANo.3

#2 では関数を使ってるけど, 同じことを配列でやることも (場合によっては) 可能.

投稿日時 - 2014-01-31 19:14:58

補足

配列でも可能ですか。
やり方を考えてみますね。

投稿日時 - 2014-02-06 16:11:32

ANo.2

面倒な条件で switch する場合、チャンと書くならこうでしょう

#define CASE_A 1
#define CASE_B 2

int 自作関数(int a){
 if (...) return CASE_A;
 if (...) return CASE_B;
 ...
 return 0;
}

(中略)

switch (自作関数(a)) {
case CASE_A: 処理A(); break;
case CASE_B: 処理B(); break;
default: 処理X();
}

投稿日時 - 2014-01-31 17:58:39

お礼

すみません
関数を使った処理はいいと思います。

ですが、ifを使っている処理だとswitchだけを使った処理速度より遅くなってしまうため使うのをためらってしまいます。

せっかく教えていただいたのですが、申し訳ありませんね

投稿日時 - 2014-02-06 16:07:54