質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

10777閲覧

【C言語】switch分の中にif文とelse if文がある意味

hasune

総合スコア18

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

1グッド

2クリップ

投稿2019/05/06 10:54

C言語のswitch文で質問があります。
switch文の中にif文とelse if文がある記述を見たのですが、
これが何をしたいのか分かりません。

switch文:式と同じものを比較して探す

if文とelse if:もし条件式が真なら処理1を、偽なら処理2を行う

という認識です。
処理速度は違うようですが、
同じ条件で同じ処理ができるものだと思っていたのでわざわざ入れ子にする意味が分かりませんでした。
調べてみてもあまりない記述方法なのか解答を得られませんでした。
お力を貸していただけないでしょうか。よろしくお願いいたします。

P.S.
C言語を勉強し始めてまだ日が浅いため、
お手間をお掛けしてしまい申し訳ありませんが、
初心者にも分かりやすいようなご回答をいただけますと助かります。
なにとぞよろしくお願いいたします。

DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2019/05/06 10:58

具体的には、どんなコードでしょうか? switch()の中と、if() の中が同じ? って事は無いですね。 見通しが悪くなるので、勧められるものではありませんが、時々は使うのではないかと思います。
showkit

2019/05/06 11:02

pepperleaf のおっしゃる通り、コードがないとわからないでしょう。 簡単に言えば、値が2つ以上のケースがある条件式を switch 文で書いてその1つケースの中で真値か偽値を持つ 条件式があれば if 文で書く。これは別に普通のことですが?
hasune

2019/05/07 10:56

いろいろとぼかしてるため分かりづらくてすみません。 記号はそれぞれ同じものが入ります。 入れ子になっているのは分かるのですが、 ここで何をしているのかが想像できません・・・。 switch(式){ case 1: if(▲▲[〇]<=■■){ 〇〇=(U4)(■■-▲▲[〇]): } else{ 〇〇=(U4)(◇◇-▲▲[〇]+■■): } break;
guest

回答3

0

ベストアンサー

条件分岐が入れ子になることは普通に起こり得ることです。ifの中にifとかswitchの中でさらにswitchということもざらにありえます。

もっとも、仰るとおり統合できることもあります。それは状況次第なのでケースバイケースです。

投稿2019/05/06 11:19

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hasune

2019/05/07 11:09

ご回答ありがとうございます。 条件分岐が入れ子はありえる話なのですね。 こういうコードで記述がされていたのですが、 cace1のifの条件が真だったら~偽だったら~ という意味なのでしょうか? switch(式){ case 1: if(▲▲[〇]<=■■){ 〇〇=(U4)(■■-▲▲[〇]): } else{ 〇〇=(U4)(◇◇-▲▲[〇]+■■): } break;
episteme

2019/05/07 11:16

難しいコト考えんでも、「switchは多方向分岐版のif」と思っていればいい。 if ( 式 == 1 ) { /* case 1: の処理 */ } else if ( 式 == 2 ) { /* case 2: の処理 */ } ... else { /* default: の処理 */ } と脳内変換すればいい。 たとえば switch 文で こうげき/ぼうぎょ/まほう/にげる におおざっぱに振り分け、 その中で if ( 僕のこうげき力 > モンスターの体力 ) { /* これで勝つる */ } したりとか よくあるコード。
hasune

2019/05/07 12:18

>epistemeさん ご回答ありがとうございます。 ifとswitchを別々に考えるのではなく、変換すればいいのですか!それは考えもしませんでした。 上記のコードでお話しますと、以下のように変換すればよいということでよかったでしょうか? switch(式){ case 1: if(▲▲[〇]<=■■){ 〇〇=(U4)(■■-▲▲[〇]):  { /* case 1: の処理 */ } } else{ 〇〇=(U4)(◇◇-▲▲[〇]+■■): { /* default: の処理 */ } } break;
episteme

2019/05/07 12:33

ちがーう。switch~caseをif ~ else if ~ else に置き換えよ
hasune

2019/05/07 12:48

>epistemeさん switch~case→if ~ else if ~ else へ変換するのですね。 そうすると疑問が浮かんだのですが、 なぜこのような書き方が存在するのでしょうか。 switch~caseとif ~ else if ~ else は似たような条件分岐だと認識しています。 switchの中にif ~ else if ~ elseを入れるよりも、 switch~caseのみの記述のほうが分かりやすいと思うのですが・・・。 記述者の好みならわかるのですが・・・。
episteme

2019/05/07 12:53 編集

switch では float や char* など、非整数の振り分けができませんし、 大なり/小なりの判定も無理。
HogeAnimalLover

2019/05/07 14:26

switchにしてもifにしてもあくまでもc言語の文法上の構文に過ぎません。つまり、処理の流れを具現化する手段でしかありません。作る人がifを使うなりswitchなり選んだ結果です。 epistemeさんの仰るとおり、switchは簡素な分岐に向きますが複雑な処理はできません。ifは複雑な分岐を実現できます。ですのでswitchをifに変換することはできますが、ifの条件をswitchで記述できるとは限りません。
stdio

2019/05/08 05:38

変なアドバイスになりますが、読みにくさが増すだけですので、switchの中にswitchはあまり使わない方が良いですよ。出来れば関数で跨いで欲しい。
hasune

2019/05/08 11:52

>epistemeさん switchでは<>など、できないことがあるのですか! 私がswitchとifの違いを調べた時に、 この2つは処理速度といった違いはあれど他に明確な違いのある条件分岐ではないとあったので 驚きました。 そうなると話は変わってきますね。switchとifの理解が深まりました。ありがとうございます!!
episteme

2019/05/08 11:54

誰だそんなてきとーコく奴は?!
hasune

2019/05/08 12:06

>HogeAnimalLoverさん 条件分岐がシンプルなものであれば、作り手の好みでifもswitchも使われるということですね。 複雑な分岐ができるifのほうがswitchよりも優秀なのですね。 今回質問しましたコードの場合、 switchだけだと<=や-などの演算ができないから入れ子にしてifを使って複雑な分岐をしれませんね。 作り手が何を考えてこのコードを作ったのか考えがぼんやりと分かってきました。 ありがとうございます。
hasune

2019/05/08 12:14

>epistemeさん いろんなサイトでswitchとifを調べたので情報を脳内変換した時にとち狂った可能性があります汗。 私の脳が悪いのだと思います。すみませんでした。 そもそも意味があるからそれぞれ個体として存在しているのに、 明確な違いがないものが2つ存在していることなんてありえませんよね。 これからじっくり理解を深めていきたいと思います。 本当にありがとうございました!!
hasune

2019/05/08 12:18

>stdioさん switchの中にswitchは書かないほうがいいのですか! 私はまだコードを書いたことがないので読みやすい読みにくいが分からず、 もしかしたらいつか自分が書く時にやってしまっていたかもしれません。 アドバイスありがとうございます!
stdio

2019/05/09 01:07

書いてみれば、なんとなく理解できると思いますよ。
hasune

2019/05/12 11:19

>stdioさん レスが遅くなってしまい申し訳ありません。 書く側になって初めて見えるものもありますもんね。 ありがとうございました。
guest

0

よい例題が難しいのですが・・・。(あまりいい例ではなくて申し訳ない)

例えば、車に関する処理で、メーカが豊田・日産・本田とそれ以外のメーカで処理を分け、また、分けたもので、年式が2010年間までと2010年以降の車で処理を分けたいとします。
そのときは、下記のように書くのが自然です。

C

1switch (メーカ) 2{ 3case 豊田: 4case 日産: 5case 本田: 6 if (年式 < 2010) 7 { 8 豊田か日産か本田の2010年年式より古い車の処理 9 } 10 else 11 { 12 豊田か日産か本田の2010年年式以降の車の処理 13 } 14 break; 15 16default: 17 if (年式 < 2010) 18 { 19 豊田か日産か本田以外の2010年式より古い車の処理 20 } 21 else 22 { 23 豊田か日産か本田以外の2010年年式以降の車の処理 24 } 25 break; 26}

全部、if 文で書くならば

C

1if ((メーカ == 豊田) || 2 (メーカ == 日産) || 3 (メーカ == 本田)) 4{ 5 if (年式 < 2010) 6 { 7 豊田か日産か本田の2010年年式より古い車の処理 8 } 9 else 10 { 11 豊田か日産か本田の2010年年式以降の車の処理 12 } 13 break; 14} 15else 16{ 17 if (年式 < 2010) 18 { 19 豊田か日産か本田以外の2010年式より古い車の処理 20 } 21 else 22 { 23 豊田か日産か本田以外の2010年年式以降の車の処理 24 } 25 break; 26}

これは、慣れた人には見にくい・・・。

全部、switch 文で書くならば・・・。

C

1switch (メーカ) 2{ 3case トヨタ: 4case 日産: 5case 本田: 6 switch (年式) 7 { 8 書けない 9 } 10 break; 11 12default: 13 switch (年式) 14 { 15 書けない 16 } 17 break; 18}

書けない。

投稿2019/05/08 00:14

showkit

総合スコア1638

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2019/05/08 04:25

>書けない。 switch( 年式 < 2010 )とすれば,caseを0と1で書けそうな気がします.
showkit

2019/05/08 04:46

書けるか書けないかで言えば、書けるでしょうが・・・。 そう書いた人のソースは、レビューすれば、くそみそに言われるのは、間違いないです。
fana

2019/05/08 04:58

「書けない」という記述だと「不可能」と捉えられ得る可能性を(別の回答のコメント欄の雰囲気等からなんとなく)危惧し,一応コメントしてみました。
showkit

2019/05/08 05:09

そういう意味ですね。了解です。 質問者さんが、不可能と思うのも問題でしょうし、「switch(年代 < 2010)」という書き方もよいのだと認識するのも問題でしょうね。難しいところですね。
episteme

2019/05/08 12:59 編集

多分岐ってゆーswitchの意義をぶっ潰すわなぁ...
asm

2019/05/08 12:05

> if (年式 < 2010) をswitchに置き換えるならば switch(年式){ case 1904: // 最古の日本車が1904年らしいのでそれ以前の型はない case 1905: case 1906: ... case 2009: 豊田か日産か本田以外の2010年年式より古い車の処理 break; default: 豊田か日産か本田以外の2010年年式以降の車の処理 } 書けるが、書きたくないし読みたくない
HogeAnimalLover

2019/05/08 12:42

さすがに「switchの中に条件式を書いて、case 0と1でニ分岐亅はナンセンスですよ。例えば、事実上禁じ手とされているgotoというものもあるわけで、文法上許されれば何でも良いというのはプログラマの発想ではないです、ユーザー側の考えならばわかりますが。ついでに、switch又はループが入れ子になると、外側breakができないことが課題です。
mpyw

2019/05/08 12:53

C言語のswitch文って整数比較しかできないような…
HogeAnimalLover

2019/05/08 13:59

>>整数比較 一応「x < y」とかの条件式も結果は整数値(真であれば1、偽であれば0)となりますので、これを使ってswitch文で分岐することは「文法上可能」です。もっとも、ナンセンスですが。
mpyw

2019/05/08 17:31

ああすいません、思い込みで文字列がcaseに書いてあると勘違いしてました…あくまで抽象的な説明で出しただけですよね
showkit

2019/05/08 22:52

asm さん、HogeAnimalLover さん、わたしの説明不足の点、補足、ありがとうございます。
fana

2019/05/09 01:49

私がコメント文にちゃんと {書きたくない,読みたくない,ナンセンス,……}的な語を明記しておけばよかったですね. switch( (年式<2010) + ((メーカ==トヨタ || メーカ==日産)<<1) ) とかなんとか書いておけば,もうちょっとそういう雰囲気が出せたかなぁ…
showkit

2019/05/09 02:25

真偽値について 誰にでもなく 補足しておけば。 C 言語で if (条件式) の中身は 1 か 0 になります。 偽が 0 で 真が 0 以外になりますので if (2) は then 条件になります。 FORTRAN だと、真が 1 で 偽が 1 以外になりますので if 文の中の条件式は注意が必要です。
hasune

2019/05/12 11:23

レスが遅くなってしまい申し訳ありません。 多くの方にコメントいただけまして本当に感謝しております。 皆様、ありがとうございました。総括でのお礼となってしまい申し訳ありません。 私の勉強不足で会話についていけていませんが、 今後の参考とさせていただきます!
guest

0

私は条件分岐が3つを超えるようならswitch文を使うようにしています。
またswitch文でもcase以下の処理が膨れ上がるようであれば、
関数テーブルにまとめてしまいます。

投稿2019/05/08 11:59

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/08 12:23

申し訳ありません。求めている回答とは違う回答をしてしまったと思います。。
hasune

2019/05/12 11:30

レスが遅くなってしまい申し訳ありません。 いつか自分がコードを書く時が来ると思うので、 どういう時にswitch文を書くか参考になります! アドバイスありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問