アプリ版:「スタンプのみでお礼する」機能のリリースについて

for文の中に分岐を作って計算するのと、if文を先に書いてからfor文にするのとではどちらが一般的ですか?

for ( i = 0; i < n; i++)
{
if ( a > b ) {
y = i;
} else {
y = i * 2;
}
printf( "%d", y );
}

とするか、

if ( a > b ) {
for ( i = 0; i < n; i++)
{
y = i;
}
} else {
for ( i = 0; i < n; i++)
{
y = i * 2;
}
}
printf( "%d", y );

とするかという事です。
ちなみにプログラムは適当ですのでちょっとしたミスはご勘弁ください。

個人的には後者の方が分岐が少ない分負担は減ると思うのですが、前者の方がすっきりとしているのでこちらを使いたいのです。

もちろん、微々たる差なので好きな方を使えという意見もあると思いますが、皆さんはどちらを使いますか?

A 回答 (6件)

基本は、「同じ(ほとんど同じ)ものが複数存在すると、必ず矛盾が発生する」という言葉に集約できるかなと思います。


後者の場合、i < n じゃなくて、i <= n だったなんていうときにどちらか一方の修正を漏らして、なおかつ、テストで、片方のループしか検証できていなかったなどということは起こりがちです。

また、コンパイラやコンピュータの負担が多い少ないは、本当にそれを考えなければならいほどシビアなときだけ気にすればOKです。
たいていの場合、最近のコンパイラは、普通のプログラマよりよっぽどうまく最適化をしてくれたりしますし。

あと、条件を整える → 実行する という2段階もありです。
この例だと、

int scale = (a > b) ? 1 : 2;
for(i = 0; i < n; i++)
{
y = i * scale;
}
printf( "%d", y );

たとえば、こんな感じ。
    • good
    • 0
この回答へのお礼

わかりやすい解説ありがとうございます。

最後のプログラムなんですが
>int scale = (a > b) ? 1 : 2;
これはaがbより大きければscaleに1を代入して、そうでなければ2を代入する
という意味でよろしいですか?
初めて見る記述だったので検索してみたのですが見つからなくて…。

お礼日時:2008/02/27 13:57

場合というか、やりたい処理によって変わると思います。



#2さんのご指摘と被りますが
(a > b)の結果に関わらず、forループは常にn回と決まっている場合、
つまりループ回数が分岐の結果に依存しない処理であれば
前者を採用するほうが理に適っていると思います。

逆に、分岐の結果がループ回数を変えてしまう「かもしれない」場合
後者を採用するほうがいいと思います。
# ただしそのままでは採用はしませんが・・・(後述)

体裁だけ見ると「同じforループが2回あって無駄」ではありますが
今のところ、たまたま回数が同じなだけ・・・というわけです。
将来、何らかの修正で変わることがありえるなら
こうしておいたほうが修正箇所が少なくて済みますよね。
(前者なら、後者に書き換えないといけなくなります)

ただ、ステップ数の多い後者をいきなり選択するような事は、普通しません。
私ならforループを関数化して後者の方法を取ります。
本当に保守のことを考えているなら、下手なコメントより関数化がベターだと思います。
    • good
    • 0
この回答へのお礼

確かに関数化がいいかもしれませんね。
ありがとうございました。

お礼日時:2008/02/28 11:38

>後者の方で作ってみることにします。


私的な意見ですので参考程度で。。。

他の方同様、場合によるという回答になりますが、
この程度のコードであれば、コンパイラの最適化によって、
最終的なバイナリ、動作はどちらで記述しても、
殆ど変わらない事が多いと思います。

本当にシビアな環境以外で、わざわざ見づらく判り難いコードを
書くことはすごいことでも、なんでもないですし、
結局、コメントを書いて汚すか、判りやすく効率悪そうに
書くかの違いなのでどっちがいいというのもないと思います。
#保守という意味ではわたしは前者を勧めます。
    • good
    • 0
この回答へのお礼

すいません、なにを思ったか前者と書くつもりが後者と書いていました。(下のコメントです)
とりあえず、前者で書いてみました。
ありがとうございました。

お礼日時:2008/02/28 11:41

場合によります



for ( i = 0; i < n; i++)
{
  if ( a > b ) { y = i;   }
  else {     y = i * 2; }
  c = y + 5;
  d = c + y + 2;
  if ( a > b ) { e = c + d + y; }
  else {     e = c + d;   }
  f = y + c + e;
  g = f + c;
  if ( a > b ) { e = g - d;   }
  else {     e = c - d + y; }
  printf( "%d", g );
}

かなり極端ですが、内容がまったく違うなら
後者の方がわかり易い場合もあるという例
    • good
    • 0
この回答へのお礼

場合によって使い分けなければいけないわけですね。
ありがとうございました。

お礼日時:2008/02/28 11:43

No.2 です。



> int scale = (a > b) ? 1 : 2;
> これはaがbより大きければscaleに1を代入して、そうでなければ2を代入する
> という意味でよろしいですか?

そうです。それで正解です。
検索は、「3項演算子」で試してみてください。
    • good
    • 0
この回答へのお礼

これは便利そうですね!
ありがとうございました。

お礼日時:2008/02/28 11:45

回答ではありませんが、私的意見としてご覧下さいませ


確かに、プログラムの負荷を考えると後者のコードになるかと思います。

しかし、見易さを考えると断然前者のコードになります。

パフォーマンスを求められるプログラムの場合、または
少しでも負荷を軽減しなければならないシステムの場合は
やむなく後者を選択するかと思います。

が、後の保守の事を考えて前者にするのが一般的と思われます。

後者のコードを記述する場合でも、しっかりコメントを挿入すれば
良いかと思われます。
    • good
    • 0
この回答へのお礼

なるほど、よくわかりました。
後者の方で作ってみることにします。
ありがとうございました。

お礼日時:2008/02/27 13:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!