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

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

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

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

11回答

18820閲覧

とある掲示板で「条件分岐は悪」という発言を見かけたのですが実際どうなんでしょうか?

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

10クリップ

投稿2015/04/25 23:16

とある掲示板で「条件分岐は悪」という発言を見かけたのですが実際どうなんでしょうか?
またその理由も教えてください。

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

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

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

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

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

guest

回答11

0

ベストアンサー

オブジェクト指向言語のポリモーフィズムの文脈では「条件分岐は悪」という考え方はありますよね。
送信側で条件分岐をして処理を変えるのではなく、受け手を抽象化してポリモーフィズムに従って実装すれば条件分岐がなくなります。

「なぜ悪なのか」という答えは、、、すみません、わかりません。複雑になるからですかね?

ちなみに、純粋オブジェクト指向言語と呼ばれている Smalltalk には他言語のような「if文」はありません。
http://ja.wikipedia.org/wiki/Smalltalk

投稿2015/04/26 03:41

kodai

総合スコア759

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

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

chokojori

2015/04/28 04:58

> 「なぜ悪なのか」という答えは、、、すみません、わかりません。複雑になるからですかね? ポリモーフィズムの文脈では、たとえば新しいサブクラスを追加することで処理パターンを増やせるのに対し、条件分岐で型判定する実装ですと、型が増えたときにすでに書かれている条件分岐に手を入れなければなりません。既存部分がテストの対象になるかならないかという違いが生じますね。
YUKI_0618

2016/09/03 09:22

関数は基本的に、行いたい処理を箇条書きにした程度のものが望ましいですよね 条件分岐は最小限にとどめ、関数が複雑になるようならいくつかの関数に分けると ポリモーフィズムなら、基底クラスやインターフェイスに必要そうな関数をすべて用意しておけば、is判定などは一切必要なくなるでしょう 以前読んだ本に、1つの関数は100行以内にするということが書いてありました 曰く、関数名がコメント代わりになるほどがよいと {   //○○の数を数える   int a = 0;   for(int i = 0....     if(△[i] == 〇〇) a++;      //全ての○○について処理   //... } ↓ {   int a = count○○(list);   Process○○(list, a); }
guest

0

あくまで推測ですが、1つの関数で何でもかんでもやってしまおうとして、引数に条件判断用のパラメータだらけ、内部ではやたらネストの深い条件分岐、というような作りのことを言っているとすれば確かにスパゲッティ化してバグの温床になりますので「条件分岐は悪」と言われるでしょう。

まあ条件分岐が全くない、ということはありえないので程度の問題だとは思いますが、将来のメンテナンスのためにもあまり複雑怪奇な構造にしないというのはコーディングの基本だと思います。

投稿2015/04/26 01:57

KoichiSugiyama

総合スコア3041

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

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

0

前にもおっしゃられている通り前後の文脈が分からないのでなんとも言えませんが、
条件分岐は私は悪ではないと思っております。
なぜなら条件分岐は必ず出てくるものですから。
それを無理に処理したりするのは逆に可読性を落とす原因になるのではないかと。

私の中での悪の条件式というと例として1つif文を挙げさせて頂くとネストの多い条件式です。
つまり
if() { // if1
if() { // if2
if() { // if3
} else {
}
} else {
}
}else{
}
のようにifが続くものは私個人は悪だと思います。
この場合if3まで処理を追う場合にif1とif2の値を頭に覚えておく必要があるからです。
つまり、バグが発生した場合にデバッグを用意の行う事ができません。
このようなif文は経験上、ある程度は解消する事ができます。

リーダブルコード等の書籍を読んでみると悪のif文がどのようなものなのかは
わかりやすくのっています。
私のこの見解も本で学び実際にやってみたところかなりスッキリしたので紹介させて頂きました。

投稿2015/04/26 07:35

編集2015/04/26 09:26
chonbo2525

総合スコア233

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

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

0

「条件分岐は悪」という部分だけを拾い出してしまうと、なかなか真意を読み取れないですね。
的を得ているかは解りませんが、思うところを書かせて頂きます。

「条件分岐は悪」という言葉が指しているところは、
手続き型プログラミングでは、if、switchをなどの条件分岐で処理を分けますが、
プログラミングでのバグの多くは条件分岐にあることが多いということに対して、
オブジェクト指向プログラミングでいえば、クラス・インスタンスを分けること、
関数型プログラミングでいえば、引数のパターンマッチを利用して分けることで、
条件分岐をしなくても処理を分け実行できるようにすれば、
バグが減るという考え方の話なのかと思います。

私個人としては、あまりそこにこだわる必要はないと思います。
プログラムはロジックだけでなく、可読性、メンテナンス性、性能やコストなど、
良い悪いというのも視点を変えれば変わります。
プログラミングにはいろいろな言語があり、流行りのようなものもがありまから、
今この考え方がいいとなっていても数年後は変わっていいることもあるでしょう。
一つの言葉に固執せず臨機応変に考えるべきかと思います。
しかし、臨機応変すぎると無秩序になるので、指針がとしては良いかもしれません。

論点がずれていたり質問の回答になってなかったらごめんなさい(^_^;)

投稿2015/04/26 06:27

yanto

総合スコア18

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

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

0

文脈が分からない以上、意図も当て推量ということになりますが…。

機械語レベルでの処理パフォーマンスの話だとすれば、条件分岐でパイプラインが吹き飛ぶケースがあってボトルネックとされることがあります。

分岐ハザード

投稿2015/04/27 03:11

nagise

総合スコア87

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

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

0

おそらくは、コンピュータの処理特性上コストが高いから出来るだけ減らせという意味合いだと思います。だとするならば該当するのはif文, switch文だけでなく、for文, while文も同じです。

コンピュータの性能が著しく向上したせいなのか、最近はあまりそういう話は聞かなくなりました。しかし今でも、大量のデータを扱う処理などでは、どうやったら少しでも速く処理させるかを考えることは必要だと思います。

投稿2015/04/26 08:43

miu_ras

総合スコア902

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

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

0

条件分岐そのものに良し悪しは無いでしょう。
条件分岐を利用して実装した結果、条件分岐の短所、長所、役どころを使いこなせているかどうかではないでしょうか。
他回答に有るように、条件分岐を利用しなくても成り立つケースが有るのに、わざわざ条件分岐を使ったら、それは結果として実装者ではなく、条件分岐が「悪」として扱われがちです。
こういう事態に陥りやすい人は、たいがい設計時に使用する言語に囚われてしまっている人がおおいです。

投稿2015/04/28 04:54

chiaki

総合スコア28

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

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

0

条件分岐は確かに悪ですが、回避法としてよく用いられる state / strategy パターンは
どうしても 大がかりすぎて、やろうとしていることに対してコストが
かかりすぎることが多い。

場合分け爆発が起こる場合、状態遷移が必要な場合というのは、
たとえば、GUIで、同じボタンがモードごとに処理が違う場合、
より具体的には、[copy]ボタンは、選択されているものが文字か図形かで処理が違ったりする。
こういう場合は、明らかに state と strategy パターンを使うべき、ということになります。
やってみれば分かりますが、かなりすっきりする場合も多いです。

ただしこれは、条件分岐が山ほど増えてきて、かつそれぞれの処理ブロックでやることが
全く違う場合であって、ほぼ同じことをするだけの条件分岐ならば、switch文などで
処理した方が 後で見ても 圧倒的に楽だし、パフォーマンス上もよいのです。

パフォーマンス性能やらリーダビリティが優れている方を取るべきで、
条件分岐を回避すべきときとそうでない場合がある、というのが真の回答で、
こういう問題こそ、グループで相談して決めるべきことかと思います。

投稿2015/05/06 09:49

okayu3

総合スコア200

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

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

0

下手なロジックを組むなという事であって、状況次第だと思います。
Cで極端な例を出すと

分岐

lang

1if (a > 0) 2 c += b; 3 4cycle++; 5if (cycle >= 16) 6 cycle = 0;

分岐なし

lang

1c += b * (a > 0); 2 3cycle++ 4cycle = cycle % 16;

一般には前者の書き方が良いとされていますね。
後者は言語機能に強い人にはすんなり把握できますが、人により一瞬???となる書き方でしょう。
個人的には分岐を使うかどうかはその処理の抽象度によります。処理が漸化式や法に基くなら分岐排除して良し、そうでなければ分岐で(ポリモーフィズムの場合も抽象度で判断)。

「悪」の発言者は、誰かから「テストで分岐のカバレッジを100%にしろ」と言われてうんざりしているとか?前者で書いてもコンパイラが後者のロジックを吐いたりしますし。

投稿2015/04/28 10:27

kppn

総合スコア44

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

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

退会済みユーザー

退会済みユーザー

2017/08/03 00:22 編集

失礼ながら、 cycle %= 16; では、cycleが17以上の場合上のプログラムと同値にならない気がするのですが…… 書くのであれば、 cycle = cycle * (cycle < 16); になるかと思います。
rubato6809

2017/08/03 01:47

なるほど、一般論というか、if文だけを見れば同値ではないけど、直前に cycle++; があるので、これはこれで良いのです。変数名"cycle"が示すように、値を  0→1→・・・15→0→1 と循環させたいことは良くあることで、常套句のようなものだからです。 さらに、16のような2のべき乗で余りを求める場合はAND演算が使えます。即ち  cycle = (cycle + 1) & 15; 最適化コンパイラがこのようなコードを生成することもあります。
guest

0

ある人はgotoを使うなと言います。ある人はネストの深いところから抜けるのにgotoを使うと言います。「ネストの深いところ」がないほうがいいのに決まっています。ただ、例外処理が実装されてない言語もあるので一概にgotoダメとは言えないところもあります。(関数の途中からreturnで戻るのも広義のgotoと変わらない)なので、私はネストが深くなりそうだったら、関数としてほおり出せばいいと思っています。・・・けっこう使いますね途中からの脱出^^;
#・・・2千行もあるCの関数見せられたら作った奴を呪いたくなります;;
すみません長々とmm

投稿2015/04/28 09:00

cateye

総合スコア6851

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

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

0

よろしければ、その掲示板のURLをご教示いただけないでしょうか。
前後の文脈が分からないと何とも言えないです。。。

投稿2015/04/26 00:46

hyper-drums-ko

総合スコア736

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問