アカウント名:
パスワード:
・移植性が低いか、ほとんどない。・再利用できない関数が大量にある。・switch文の中に5case以上書かれている。・プログラムがどう動いているかを説明できるのが書いた当人だけ。
納期で叩かれたら、どんな名プログラマでもクソコードを吐くだろうと思っています。
>switch文の中に5case以上書かれている。これは違うと思う。分岐が非常に多い場合は、いずれにせよ非常に多くのcaseやif文が必要になる。その場合だと、switchを使うのが一番綺麗な場合がある。クラス構造とポリモフィズムに置き換えた方が綺麗になる場合もあるが、いつもそうなるとは限らない。そもそもC言語だと無理だしね。
この手の処理で困るのが、switch( flag ){case 1: ret = funcA(); break;case 2: ret = funcB(); break;
.....
default: .....}
と関数やメソッドで分割して書かずに、そこに直接ベタで処理を書くこと。特に上記funcA()やfuncB()の中身が百行以上に及ぶ場合は、後のメンテが面倒になる。
言語によってはオートインデントもマトモに使えないしで、けっこうな地獄を見ることもあるよ。
あと、break; を省略するコードを書く時は、ちゃんとコメント付けろってのもあったなあ。
んー、多分「5個以上の分岐をするんだったら関数テーブル作ったほうが効率的」と言う話じゃないかと思います(^_^;
void foo(int arg1){}
と言う型で統一したエントリ関数を作っておいて、分岐後の処理はここでやるようにする。で、
void (*table[5])(int) = {func0, func1, func2, func3, func4};
とか言うアドレステーブルを作っておいて(文法に自信ないけど)、実際のcase分岐は
void branch_f(int index, int arg){ void (*ptr)(int); if(index >= 5) return; ptr = table[index]; if(ptr != NULL) ptr(arg); return;}
とかやっちゃう訳ですよ。# 色々とツッコミどころがある気がするが、そこら辺はコンパイラのチェック通してないので;-)
CPUエミュレータとかの物凄い大きな分岐をやるときにこの手のテクニックを使いますが(後、同じ分岐が何百回も繰り返されるので流石にコスト考えたらね…とか)。
>んー、多分「5個以上の分岐をするんだったら関数テーブル作ったほうが効率的」と言う話じゃないかと思います(^_^;
すくなくとも #2301000 の方にはそのように書かれてません。もしそれを意図したものだとしたら、問題文の方に誤りありですな。
switch文の中に5case以上書かれている。
いや、必要であればむしろswitch文で書いてくれないと困りますが。(全部if~elseとか)酷く見えるのは処理の分割(後述)がされていないからでしょう。
switch文の使い方でなんとかしたいのは
この辺でしょうか。
一般的には多重ネストや分岐後の処理がどうしても長くなるなら、関数に分けるなどすべきです。# 関数呼び出しのオーバヘッドとかを気にしないといけないような場合は除く。
分岐後の処理がやたらと長い場合、
差分ツールが出した差分行数から単体テストの実施数が決められていて、その単体テストというのがデバッガで一行一行確認して変数の中の値をエクセルに貼り付けていくという苦行を強いられていた頃はよく歪な条件分岐を使っていたなー(遠い目)
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
アレゲはアレゲ以上のなにものでもなさげ -- アレゲ研究家
職業プログラマじゃないけど、「悪いコード」を想像してみました。 (スコア:0)
・移植性が低いか、ほとんどない。
・再利用できない関数が大量にある。
・switch文の中に5case以上書かれている。
・プログラムがどう動いているかを説明できるのが書いた当人だけ。
納期で叩かれたら、どんな名プログラマでもクソコードを吐くだろうと思っています。
Re:職業プログラマじゃないけど、「悪いコード」を想像してみました。 (スコア:1)
>switch文の中に5case以上書かれている。
これは違うと思う。
分岐が非常に多い場合は、いずれにせよ非常に多くのcaseやif文が必要になる。
その場合だと、switchを使うのが一番綺麗な場合がある。
クラス構造とポリモフィズムに置き換えた方が綺麗になる場合もあるが、
いつもそうなるとは限らない。そもそもC言語だと無理だしね。
この手の処理で困るのが、
switch( flag ){
case 1:
ret = funcA();
break;
case 2:
ret = funcB();
break;
.....
default:
.....
}
と関数やメソッドで分割して書かずに、そこに直接ベタで処理を書くこと。
特に上記funcA()やfuncB()の中身が百行以上に及ぶ場合は、後のメンテが面倒になる。
言語によってはオートインデントもマトモに使えないしで、
けっこうな地獄を見ることもあるよ。
あと、break; を省略するコードを書く時は、ちゃんとコメント付けろってのもあったなあ。
Re:職業プログラマじゃないけど、「悪いコード」を想像してみました。 (スコア:1)
んー、多分「5個以上の分岐をするんだったら関数テーブル作ったほうが効率的」と言う話じゃないかと思います(^_^;
と言う型で統一したエントリ関数を作っておいて、分岐後の処理はここでやるようにする。
で、
とか言うアドレステーブルを作っておいて(文法に自信ないけど)、
実際のcase分岐は
とかやっちゃう訳ですよ。
# 色々とツッコミどころがある気がするが、そこら辺はコンパイラのチェック通してないので;-)
CPUエミュレータとかの物凄い大きな分岐をやるときにこの手のテクニックを使いますが(後、同じ分岐が何百回も繰り返されるので流石にコスト考えたらね…とか)。
Re:職業プログラマじゃないけど、「悪いコード」を想像してみました。 (スコア:1)
>んー、多分「5個以上の分岐をするんだったら関数テーブル作ったほうが効率的」と言う話じゃないかと思います(^_^;
すくなくとも #2301000 の方にはそのように書かれてません。
もしそれを意図したものだとしたら、問題文の方に誤りありですな。
Re: (スコア:0)
いや、必要であればむしろswitch文で書いてくれないと困りますが。(全部if~elseとか)
酷く見えるのは処理の分割(後述)がされていないからでしょう。
switch文の使い方でなんとかしたいのは
この辺でしょうか。
一般的には多重ネストや分岐後の処理がどうしても長くなるなら、関数に分けるなどすべきです。
# 関数呼び出しのオーバヘッドとかを気にしないといけないような場合は除く。
分岐後の処理がやたらと長い場合、
Re: (スコア:0)
差分ツールが出した差分行数から単体テストの実施数が決められていて、
その単体テストというのがデバッガで一行一行確認して変数の中の値をエクセルに貼り付けていくという苦行を強いられていた頃は
よく歪な条件分岐を使っていたなー(遠い目)