• ベストアンサー

if文の中にfor文なのか、for文の中にif文なのか

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 ); とするかという事です。 ちなみにプログラムは適当ですのでちょっとしたミスはご勘弁ください。 個人的には後者の方が分岐が少ない分負担は減ると思うのですが、前者の方がすっきりとしているのでこちらを使いたいのです。 もちろん、微々たる差なので好きな方を使えという意見もあると思いますが、皆さんはどちらを使いますか?

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

  • ベストアンサー
回答No.2

基本は、「同じ(ほとんど同じ)ものが複数存在すると、必ず矛盾が発生する」という言葉に集約できるかなと思います。 後者の場合、i < n じゃなくて、i <= n だったなんていうときにどちらか一方の修正を漏らして、なおかつ、テストで、片方のループしか検証できていなかったなどということは起こりがちです。 また、コンパイラやコンピュータの負担が多い少ないは、本当にそれを考えなければならいほどシビアなときだけ気にすればOKです。 たいていの場合、最近のコンパイラは、普通のプログラマよりよっぽどうまく最適化をしてくれたりしますし。 あと、条件を整える → 実行する という2段階もありです。 この例だと、 int scale = (a > b) ? 1 : 2; for(i = 0; i < n; i++) { y = i * scale; } printf( "%d", y ); たとえば、こんな感じ。

rodoni
質問者

お礼

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

その他の回答 (5)

  • piyo2000
  • ベストアンサー率49% (144/293)
回答No.6

場合というか、やりたい処理によって変わると思います。 #2さんのご指摘と被りますが (a > b)の結果に関わらず、forループは常にn回と決まっている場合、 つまりループ回数が分岐の結果に依存しない処理であれば 前者を採用するほうが理に適っていると思います。 逆に、分岐の結果がループ回数を変えてしまう「かもしれない」場合 後者を採用するほうがいいと思います。 # ただしそのままでは採用はしませんが・・・(後述) 体裁だけ見ると「同じforループが2回あって無駄」ではありますが 今のところ、たまたま回数が同じなだけ・・・というわけです。 将来、何らかの修正で変わることがありえるなら こうしておいたほうが修正箇所が少なくて済みますよね。 (前者なら、後者に書き換えないといけなくなります) ただ、ステップ数の多い後者をいきなり選択するような事は、普通しません。 私ならforループを関数化して後者の方法を取ります。 本当に保守のことを考えているなら、下手なコメントより関数化がベターだと思います。

rodoni
質問者

お礼

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

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

>後者の方で作ってみることにします。 私的な意見ですので参考程度で。。。 他の方同様、場合によるという回答になりますが、 この程度のコードであれば、コンパイラの最適化によって、 最終的なバイナリ、動作はどちらで記述しても、 殆ど変わらない事が多いと思います。 本当にシビアな環境以外で、わざわざ見づらく判り難いコードを 書くことはすごいことでも、なんでもないですし、 結局、コメントを書いて汚すか、判りやすく効率悪そうに 書くかの違いなのでどっちがいいというのもないと思います。 #保守という意味ではわたしは前者を勧めます。

rodoni
質問者

お礼

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

  • nak777r
  • ベストアンサー率36% (49/136)
回答No.4

場合によります 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 ); } かなり極端ですが、内容がまったく違うなら 後者の方がわかり易い場合もあるという例

rodoni
質問者

お礼

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

回答No.3

No.2 です。 > int scale = (a > b) ? 1 : 2; > これはaがbより大きければscaleに1を代入して、そうでなければ2を代入する > という意味でよろしいですか? そうです。それで正解です。 検索は、「3項演算子」で試してみてください。

rodoni
質問者

お礼

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

  • suzubuta
  • ベストアンサー率0% (0/1)
回答No.1

回答ではありませんが、私的意見としてご覧下さいませ 確かに、プログラムの負荷を考えると後者のコードになるかと思います。 しかし、見易さを考えると断然前者のコードになります。 パフォーマンスを求められるプログラムの場合、または 少しでも負荷を軽減しなければならないシステムの場合は やむなく後者を選択するかと思います。 が、後の保守の事を考えて前者にするのが一般的と思われます。 後者のコードを記述する場合でも、しっかりコメントを挿入すれば 良いかと思われます。

rodoni
質問者

お礼

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

関連するQ&A

  • if~else文の中にまたif~else文をいれるには。

     このプログラムを思うように実行したいのですが、できません。 コンパイルはできるのですが、警告が4つほど出て、結果も自分が思ってるのとは違います。 プログラムのどこを改善すべきか教えてください。 OSはWindows XPで、コンパイラはボーランドのフリーコンパイラを使用しています。 #include<stdio.h> int main(){ int a,b,c,d; printf("1か0を入力してください。\n"); scanf("%d",&a); if(a=0) { printf("2か3を入力してください。\n"); scanf("%d",&b); if(b=2){ printf("今まで合計は%dです。\n",a+b); } if(b=3){ printf("今まで合計は%dです。\n",a+b); } else { printf("指定した数字を入力して下さい。\n"); } } else if(a=1) { printf("あなたは%dを入力しました。\n",a); } else { printf("指定した数字を入力してください。\n"); } return 0; }

  • if文の演算子について

    if文の演算子について int a=0,b=1,c=1,d=1; if(a==1 && b==1 && c==1 ||d==1){ Printf("yes"); }else{ Printf("no"); } if((a==1 && b==1 && c==1 )||d==1){ Printf("yes2"); }else{ Printf("no2"); } } 上記のif文で出力結果が異なります。 if((a==1 && b==1 && c==1 )||d==1)の方はa=1、b=1、c=1の時もしくはd=1の時と 理解できるのですが、 if(a==1 && b==1 && c==1 ||d==1)の方は、どういう条件の時が当てはまるのでしょうか?

  • if文について

    ソートのプログラムにおいて昇順・降順を選択して表示させるプログラムを書いてるのですが 下記のように記述するとエラーが出てしまいます。 よく調べたのですがエラー表示もよくわからないものなのでした。 どのようにすればうまく動くようになるのでしょうか? #include <stdio.h> #define swap(type, x, y) do {type t = x; x = y; y = t; } while (0) void bubble(int a[], int n) { int i, j; for (i = 0; i < n - 1; i++) { for (j = n - 1; j > i; j--) if (a[j - 1] > a[j]) swap(int, a[j - 1], a[j]); } } void bubble2(int a[], int n) { int i, j; for (i = 0; i < n - 1; i++) { for (j = n - 1; j > i; j--) if (a[j - 1] < a[j]) swap(int, a[j - 1], a[j]); } } int main(void) { int i; int x[7]; int nx = sizeof(x) / sizeof(x[0]); int select; printf("%d個の整数を入力せよ。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d] : ", i); scanf("%d", &x[i]); } printf("昇順ですか降順ですか? 0:昇順/1:降順 >"); scanf("%d",&select); if (select == 0) bubble(x, nx); puts("昇順にソートしました。"); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); else bubble2(x, nx); puts("降順にソートしました。"); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); return (0); }

  • 配列やif文について

    課題がでました。 最大で30個の整数を入力し、それを大きい順に並び替えるプログラムを 1次元配列と繰り返し・if文を使い作成しなさい。 例は input 12 8 90 the large order 90 12 8 という課題がでました。 ここの方なら簡単とは思いますが、よろしくお願いいたします。 自分で作ったプログラムは #include <stdio.h> main() { int a[30]; int n; int imax; int work; int max ; int i,k; printf("seisuunokosuu(<=30)="); scanf("%d",&n); for(i=0;i<n;i++){ printf("input.%2d=",i+1); scanf("%d",&a[i]);} for(i=0;i<n;i++){ imax = i; max = a[imax]; for(k=i+1;k<=n;k++){ if(a[k] > max){ imax =k; max = a[imax]; } } work = a[i]; a[i] = a[imax]; a[imax] = work; } for(i=0;i<n;i++){ printf("%d\n",a[i]); } return(0); } ですが、繰り返し・if文(一度)をつかっていません。 アドバイスの方よろしくおねがいいたします。

  • for文~break

    break文に達した時、for文から抜けますか?それとも、if { }から抜けるんですか? for文はどこまで影響下にありますか? if ( i==5 ) printf ("サーバーが見つかりません"); まででしょうか? また  if ( i == 5 ) で5なら、実行としていますが、 6,や,8など5 以外でも、サーバーが見つかりません と if文が実行される見たいですが、なぜですか? 教えてください。 #include<stdio.h> int main(void) { int array[5][2]={ {1,14}, {2,28}, {3,19}, {4,8}, {5,15}, }; int sever; int i; printf("番号を入力してください"); scanf("%d",&sever); for( i=0 ; i<5 ; i++ ) if ( sever == array[i][0] ){ printf ( "%d 番には, %d 人います。\n",sever,array[i][1]); break; } if (i==5) printf("サーバーが見つかりません"); return 0; }

  • 奇数魔方陣

    下記のプログラム(奇数魔方陣) について最初のfor文からどのような処理が行われているかわかりません。 { int mahoujin[10][10],x,y,i,n = 7; x = n / 2 + 1; y = 1; mahoujin[x][y] = 1; for( i = 2; i <= n * n; i++ ){ if( i % n == 1 ){ y = y + 1; }else{ x = x + 1; y = y - 1; } if( x > n ) x = 1; if( y < 1 ) y = n; mahoujin[x][y] = i; } for( y = 1; y <= n; y++ ){ for( x = 1; x <= n; x++ ){ printf( "%3d ", mahoujin[x][y] ); } printf( "\n" ); } 特にわからないのがif文で分岐になるところどのようなことが行われているかがわからないです。どなたか教えて頂けるとうれしいです。

  • for文

    for文なのですが、 scanfで得た、 iを for文のi--で、一づつへらしてますが、 0でfor文がおわりますが 0で終わりの記述がない気がするんですが、 どうしてでしょか? int main(void) {    int i;    printf("正の整数を入力してください。\n");    scanf("%d",&i);    for( ; i ; i--)    printf("qが入力されました。\n");    return 0; }

  • elseif文の中のif文のところで

    今、c言語の勉強をしていまして、 演習問題のプログラムを作成しています。 elseif文の中のif文のところで エラーが出てしまうのですが・・・。 ご教授して頂けたら幸いです。 #include<stdio.h> int main(void) { int kyori,untin; printf("ようこそ \n"); printf("距離を入力してください->"); scanf("%d", &kyori ); if(kyori < 5) untin = 120; else if(kyori >= 5 && kyori < 21) untin = ((kyori-4)/2*20)+120; else if(kyori >= 21 && kyori < 1000) untin = ((kyori-20)/5*40)+280; //7840円 else if(kyori >= 1000 ) untin = ((kyori-1000)/10*50)+8120 ここでエラー→→→ if(untin <> 0) untin = untin + 50; printf("運賃は%dです。",untin); }

  • if文の中に

    例えば if(a<0){ if(a<b) c=a+b } ように if文の中にif文を入れる事はできるのですか? また、if-else文はif() →else if() →elseと続きますが、 これ以降(4つ以上の選択肢) に繋げたい時はどうすればいいですか? 教えて下さい!

  • if文の中のif文・・・について

    質問させていただきます。 if文の中のif文の記述の仕方について質問があります。 例えば if ( x > 0 ){ a = b+c; if ( a > 1) d = e+f; ・・・1 if ( a < 1) d = e-f; ・・・2 if ( a = 1 ) d = 1-g; ・・・3 } h = d + i; aが1より大きい場合は、1の処理を、aが1より小さい場合は2の処理を、aが1と同じであった場合、3の処理をして最終的に、h = d + i;の式の d に代入して h を求めたいと思っているのですが、うまくゆきません。 if文の中のif文の記述はどのようにすればよいのでしょうか? よろしければご教示よろしくお願いします。

専門家に質問してみよう