- 追加された行はこの色です。
- 削除された行はこの色です。
- TIPS は削除されています。
- TIPS の差分を削除
*TIPS [#k98e792e]
新しいページを作ってまとめるほどではないけれどもスレでちょこちょこっと話題になった技術的なお話をメモする所です。~
有益な情報がたらたらと流れていってしまっている気がしたので作りました。スレでの役に立つFAQなんかをどんどん書き足していって下さい。~
初歩的なことでも遠慮せずに気軽に書き込めたらと思います。
#contents
**プログラミング関連 [#sce13b6a]
*** try~catchの使いどころ [#ba12fc38]
&color(blue){593 以下、名無しにかわりましてVIPがお送りします [sage] Date:2009/06/25(木) 10:07:05.32 ID:kkNfJZRU0};~
・例外が投げられうる場所でtry~catchを使っておかないとプログラム全体が落ちる~
これが最も重大なtry~catchの使いどころ~
catchの中でリソースリークを防ぐコードを書いたり、メッセージを表示するのは、意味的には二次的なものになるだろう
&color(blue){596 以下、名無しにかわりましてVIPがお送りします [sage] Date:2009/06/25(木) 10:17:12.63 ID:Bbxi1UV40};~
.NetFrameworkだとエラー発生時にcatchしないとCLRが自動的に検出したりする~
そういう時に必ずエラーで落ちたりするのでエラーが発生しかねない箇所にはエラーを貼る~
後は実際の業務でも、同じExceptionでも層ごとに業務の独自例外を投げたりするので
そういう時は便利
&color(blue){597 以下、名無しにかわりましてVIPがお送りします [sage] Date:2009/06/25(木) 10:33:47.30 ID:kkNfJZRU0};~
明らかに使い方が間違っていることに起因する例外ー(.NETだとArgumentException等)、起こる=バグなので、処理せずにおくのが(デバッグの都合上)好ましい~
一方で、正しく使っていても起こりうる例外(ファイルアクセスやネットワーク系等)は、起こることが予め想定されているのだから、例外処理をせずに落ちる方がバグ~
例外の投げ方については2つの使い方があり、
+処理が失敗したことを呼び出し側に伝え、然るべき処理を行わせる
+関数ネストの深い場所から一気に抜ける
1. は通常の使い方、というか本来の形。ライブラリのメソッドが提供する例外の投げ方と同じだな
2. は特定の処理の内部でのみ使う形。単にいちいちreturnするのを省略しているだけなので、決してトラップを忘れて外に出してはならない
&color(blue){724 名前:以下、VIPにかわりましてパー速民がお送りします[] 投稿日:2009/06/25(木) 11:14:05.13 ID:Tv/kdEM0};~
>実際の開発の現場では、2. のような場合も一般的に例外が使われているのでしょうか?
決して「一般的」では無いが、㌧でもない設計のコードを直さなきゃならん場合とかに、急避難的なパッチとして使うケースがある。~
無論、それに起因したバグってのが有り得る(そしてそれは発見し難い)ので決して絶対に口が裂けても推奨は出来ないが、デスマーチから逃れる為の劇薬ともなる。~
>catch&tryで記述した方がコードの見通しが格段によくなる場合がありそうです
実際に多々ある。関数の途中でreturn;とか書く香具師が跡を絶たない理由だな。~
そうすることで「本来の主要な処理」を「処理順序通り」に「間に長々としたエラー処理を挟むことなく」書くことが出来るからな。~
それは、何処から何処までがエラー処理なのか、とか考えなくて済むので見通しが良い。
&color(blue){720 名前:以下、VIPにかわりましてパー速民がお送りします[] 投稿日:2009/06/25(木) 10:22:31.41 ID:Tv/kdEM0};~
「研究分野とは関係無いんだけどプログラムとして書かなきゃならないエラー処理」ってのがあるでそ?~
それが「例外」なんで、其処で処理するのに書く。~
例えば指定したファイルが開けなかった場合・・・はやりすぎだけど、アルゴリズム検証用に画像サイズが2の冪数でなきゃならないプログラムを書いたとする。~
なのに画像サイズが2の冪数でないことが判明した時とかにthrowで投げるとか。~
同じく検証用にモノクロで検証しようって時にカラー画像が指定されていることが判明したらthrow投げるとか。~
で、その全体をtryで囲っておいて、catchで「検証用なんで、読み込める画像には制限があるます」とか表示させて終了したりする。~
同じように、作業用メモリーを確保しようとしたら失敗したとか、ファイルを読み込もうとしたら途中で止まった(多分途中で切れていた)とか、とにかくもうどうにも出来ん時にも例外を投げる。~
最大の使いどころは、画像処理部分だけの関数を作った時(そしてライブラリー化して使いまわそうとした時)で、画像処理部分でエラーが出ても、それをどう処理するかをアプリケーションに任せたい場合。エラーが出たらthrowで例外を投げるようにする。~
この場合は必ずしも「エラーが出たら即終了」が最善ではないから、アプリケーションが何か特別な処理をしたいはずだ。その時はアプリケーション側でtry~catchを使う。
&color(blue){738 名前:以下、VIPにかわりましてパー速民がお送りします[] 投稿日:2009/06/25(木) 16:58:14.85 ID:Tv/kdEM0};~
>例外のcatchをもってチェックの代替にしても良かったりするのだろうか~
良い。ものすごいのになると、ダイアログでキャンセルを押されたら例外を投げる、というライブラリー群も存在するぐらいだ。~
スレ内で何人か「例外というのは想定の範囲外を処理するもの」と言っているが、これは昔(例外を含んだオブジェクト指向設計の普及以前)からのプロの考え方で、「予測可能な全てに対処する(=エラー処理を完璧にする)のがプロだ」という正しい考え方に基づいている。~
それ自体は今でも正しいが、其処から派生して、「例外」は予測不能な事態に対処する為のものであり、予測可能ならあらかじめifでチェックするべし、という方向に進んでしまう傾向にある。~
新しく現れた「例外」の扱い方に慣れてないわけだな。~
そうではなく、「例外」は「順調に進むはずである処理の流れ」を妨げる時に使うものだ。~
日本語で言うなら、「~~をし、次に~~をし、そして~~をする。但し~~の場合は例外とする」という感じ。~
そういう意味で「例外」ってのは適切な名前。~
先の「ダイアログでキャンセルを押されたら例外」で言うと、「ユーザーが指定したファイルを開き、こねくり回して、上書きする関数である。但しユーザーが途中でキャンセルした場合は例外とする」ってことになるわけだ。~
如何なる例外で処理が中断されたかを呼び出し側が判別し、それに適切な処理(例えばユーザーにアラートを出すとか)を行えばいい。
&color(blue){54 以下、名無しにかわりましてVIPがお送りします [sage] Date:2009/07/03(金) 11:11:48.29 ID:haLfR9oX0};
int error = 0;
try { func(); }
catch(...) { error = 1; }
と
int error = 1;
try { func(); error = 0; }
catch(...) { }
だったらどちらがいいと思う?
&color(blue){801 名前:以下、VIPにかわりましてパー速民がお送りします[] 投稿日:2009/07/03(金) 11:43:35.70 ID:SQ0dFv.0};
あえてどちらか、と言うのなら、安全性と意味付けの両観点から後者を推す。理想的には
bool isDone = false;
try { func(); isDone = true; }
catch(...) { }
だろうか。~
短い処理しかしないなら前者でもcatchの中でerror=1;されていることはすぐにわかるが、~
ある程度の長さの処理がされるようになると、error=1;することを見落とす可能性が出てくる。~
するとcatchを追加した時等に問題が起こることになる。そしてそのバグは発見が困難だ。~
また、例外処理が「問題が起きた時」に処理する内容を記述するのに対し、件の記述は「問題が起きなかった時」のための記述である。~
それを「問題が起きた時」の処理として記述することはコードの記述とコードの意味に差異を作ることであり、~
それはコードを「素直に読む」と誤解する可能性を持つ。つまりバグの元だ。
***動的に多次元配列をとる場合について(C++) [#o853c06a]
&color(blue){213 以下、名無しにかわりましてVIPがお送りします [] Date:2009/06/27(土) 02:26:49.46 ID:EGWRrnpD0};~
Cの**ポインタ変数なんて一般的に使う機会あんの?
&color(blue){216 以下、名無しにかわりましてVIPがお送りします [] Date:2009/06/27(土) 02:29:47.12 ID:Cc5wComw0};~
>>213 まともな企業なら コメント以外の**は ツールではじかれる
&color(red){''ではどうするか''};
-動的にとる場合
-- vector< vector<int> >
-静的にとる場合
--boost::array(メモリサイズを動的に変化させない場合)
-一方のみ動的にとる場合
--1次元配列で表現~
固定 →~
行0: [0][1][2][3][4]~
行1: [5][6][7][8][9]~
: 動的↓~
~
添え字から位置~
int x = index%5;~
int y = index/5;~
~
位置から添え字~
int index = y*5+x;~
~
--int (*a)[5] = (int(*)[5])malloc(sizeof(int[10][5]));~
typedefすると↓~
typedef int int5[5];~
int5 *a = (int5*)malloc(sizeof(int5[10])); ~
***ポインタの概念(C) [#ub2f1737]
&color(blue){24 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 01:59:49.34 ID:6muMq0T70};~
94 以下、名無しにかわりましてVIPがお送りします [] 2009/12/07(月) 22:42:53.16 ID:QJBGRg+1P~
ぶっちゃけポインタの仕組み自体はそもそも大した話じゃない。~
「わからない」 と言う人の大半は、それ自体がわからない訳じゃなくて、恐らく次のようなタイプに分かれる希ガス~
~
「使い方が」わからない人の分岐)~
A.参照すらも知らない = メモリモデルのイメージが頭に染みていない。よってメリットも理由もわからない~
B.は?参照だけでいいんじゃねーの? = あえて 「ポインタ変数」 自体に拘る理由がわからない~
C.興味が無いので追っていない = 分かろうとする気が無い~
D.がくれきがくれき
&color(blue){25 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:03:16.17 ID:ek2ADDL50};~
変数は数字とか文字とかを入れる箱~
ポインタはそんな箱を監視してる人~
でもこの人はたいへん頭が悪く、数字しか監視できなかったり~
文字しか監視できなかったりするんです。~
~
int x=10; //xという箱に10をいれなさい
int* person; //数が入った箱を見るための人を作りなさい
person = &x; //その人にxの箱を監視させなさい
*p=50; //監視しているものを50にしなさい。
&color(blue){26 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:05:00.04 ID:Hi1JjsdgP};~
E. こういう酷い説明が出てくるから分からなくなる
&color(blue){27 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:07:33.26 ID:j8OH0pW50};~
F. 説明を眺めて揚げ足を取るだけで、質問するなどの理解する努力をしない
&color(blue){30 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:13:12.90 ID:D3SXyNcE0};~
G.ポインタ自体が世の中の流れに取り残されてる
&color(blue){31 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:15:51.52 ID:69vu7Nzc0};~
H. 自民党が悪い、政権交代したのでそろそろわかるようになる
&color(blue){28 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 02:12:35.05 ID:SkcH5QNZP};~
監視してる人の頭をよくするためにはどうすればいいですか
&color(blue){35 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 03:11:58.63 ID:zxJH6QGEO};~
参照はポインタの糖衣構文です
&color(blue){36 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 03:23:45.99 ID:E/ThOpvQP};~
ポインタは間接アドレッシングの糖衣構文です
&color(blue){37 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 03:38:16.63 ID:j8OH0pW50};~
>>28監視してる人を監視する人(ガーベッジコレクターとか)を作ればいいんじゃね?~
>>35違うます。参照は機能制限版ポインターであって、異なる構文なのれす。~
例えば参照には実体が必要なので、インクリメントすることが出来ません。~
>>36ポインター以外の間接アドレッシング構文が無いんだから、糖衣構文では有り得ないだろ常識的に考えて・・・
&color(blue){75 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 13:20:36.28 ID:ZTmjYaWQ0};~
wikiのCのポインタの注意のところでさ、~
~
int* a, b, c; これはあきらめて
int *a, *b, *c; こう書いてください
~
ってあるけど、俺は~
~
int* a;
int* b;
int* c; こう書いてください
~
のほうがいいと思うんだがどうか。
&color(blue){78 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 13:31:21.23 ID:LpQFoyZd0};~
>>75~
そうするなら~
~
int *a;
int *b;
int *c;
~
のほうがいいな
&color(blue){84 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 13:47:57.70 ID:ZTmjYaWQ0};~
(中略)~
>>78~
それはなにゆえ?それだけは無いわ、と思うのだが。
&color(blue){86 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 13:56:56.31 ID:LpQFoyZd0};~
>>84~
Cで int * a; と書いた場合、これは「int* 型の a」ではなく「int 型の *a」を意味するから~
~
前者であれば int* a, b, c; と書いた時に a, b, c が全て int* 型となるはずで、~
後者であれば a は int* 型、b, c が int 型になるはず~
~
言うまでもなく、実際には後者であるから、~
int *a; のように *a を繋げて書いた方がより相応しい
&color(blue){87 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 13:56:58.27 ID:E/ThOpvQP};~
int* a;派ではあるけど、*は変数に係るからint *a;のほうが実態に合ってるとは思う
&color(blue){88 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 14:00:50.47 ID:LpQFoyZd0};~
C#だと int* a, b; で両方ともポインタになるんだがな
&color(blue){89 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 14:03:37.43 ID:Hoc97OQq0};~
vector<int *>ってするけどな~
vector<int*>はきもち悪い
&color(blue){90 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 14:11:23.84 ID:ZTmjYaWQ0};~
>>86~
つまり、今回の話題うんぬんじゃなくて、そもそも「int* a;」に反対ってことか。~
~
宣言構文の実態にそってるのは確かにint *aなんだけど、~
「ポインタ型」っていう概念として実態にそってるのはint* aであって、~
むしろCでも>>88であるべきだと思う。~
~
つまり、Cの言語仕様にそもそもちぐはぐな部分があるので、~
初心者がそんなことにまどわされないで済むためにはいっそ~
「(少なくともポインタ変数は)1行で1個しか宣言しない」をお勧めしたほうがいいんじゃないかと。
&color(blue){93 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 14:26:38.90 ID:LpQFoyZd0};~
>>90~
流石に今更Cを根本から覆すのは無理だからなぁ……確かに>>88の方がいいんだけど~
特に int *p = &i; みたいなのになってくるとややこしい~
*p = ○○; の場合は (*p) = ○○; なのが、int *p = ○○; になると int (*(p = ○○)); になって、~
解釈の順序が変わるからなぁ……~
~
初心者に、という点で考えるなら、非ポインタについても1変数1文を徹底した方がよりよいかと~
非ポインタで int i, j; とすることを教えると、どうしても必ず int* p, q; ってしたくなってハマるから~
ならば最初から、複数のポインタ変数を1文で宣言する場合を叩き込んでおいた方がいい
&color(blue){96 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 15:41:25.94 ID:ZTmjYaWQ0};~
>>93~
>1変数1文を徹底した方がよりよい~
そうだよね。見解は一致した。~
それを徹底してねといいつつ、知識として、1行でするやり方も教えるのが良い。~
~
一致したところで、C使いのみなさんは1行で複数宣言ってけっこうすんの?~
俺は必ずといって良いほど1行1個にしてるんだけど。~
~
理由は、~
・削除やコメントアウトがしやすい(複数あると、1個だけいらなくなったときめんどい)~
・途中でブロックを作りまくって変数のスコープを最低限に抑えてるので、~
そもそも1箇所で宣言する量が少ない
&color(blue){98 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 16:00:49.76 ID:j8OH0pW50};~
>>90~
>「ポインタ型」っていう概念として~
概念としての「ポインタ型」ってのは、そもそもCには無かったわけで。~
むしろ、ポインターと参照の関係(>>37)のように、アセンブリ言語における間接アドレッシングとポインターの関係があるわけで。だからこそ>>35-36のような表現になるわけで。~
初学者にとっては「アセンブリ言語における間接アドレッシング」の概念が無いから、「ポインタ型」という概念をでっちあげて教えてるだけで、~
ポインターは本来なら間接アドレッシングに型の縛り(intとかcharとか)を与えたものであって型とは違う。~
でもそれを第一級オブジェクトにしたことで、第一級オブジェクトは全て型がある→ポインター型である、と再解釈されることになっただけだ。~
この本来なら異なる概念を一つに纏めて扱おうとするから、ちぐはぐなところが出てきてる。~
そして、ポインターから旧態依然とした間接アドレッシングの概念を無くし洗練させたのが参照。~
>>94そいつらの主張する「わかり易い」ってのは、「同じものを二度書かない」ってだけの話だと思ふw~
>>96場合によっては一行で複数宣言する。それらが「まとまっていることで意味がある」集合なら特に。
&color(blue){99 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 16:22:24.62 ID:ZTmjYaWQ0};~
>>98~
なるほど、一口に「ポインタ型という概念」なんていってしまうと、壮大な語弊があるわけか。~
この考えでずっと問題なかったのでそのままにしていたが、~
より理解が深まった。ありがとう。
&color(blue){100 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 16:23:55.94 ID:Hoc97OQq0};~
頑張って長文書くくらいならwikiにでも載せればいいと思う
&color(blue){101 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 16:31:40.48 ID:j8OH0pW50};~
>>100話には流れってものがあるんだぜ?
&color(blue){102 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 16:49:26.53 ID:ZTmjYaWQ0};~
しかしスレ内で、ネットの波に飲まれて消えるのがもったいない会話が~
たまになされるのも事実なんだよなぁ。
&color(blue){116 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 17:58:29.12 ID:ceii95ly0};~
>>102~
つhttp://vipprog.net/wiki/TIPS.html
&color(blue){117 :以下、名無しにかわりましてVIPがお送りします:2009/12/09(水) 18:03:26.44 ID:ZTmjYaWQ0};~
>>116~
知らないからな!~
いいだしっぺの法則なんて知らないからな!~
~
やるならやるで持ってる過去ログ全部漁ってこないと気がすまない…。
** アルゴリズム関連 [#a8ea9877]