1 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:27:18 ] C言語の*入門者*向け解説スレッドです。 ★前スレ C言語なら俺に聞け(入門編)Part 60 pc12.2ch.net/test/read.cgi/tech/1264920499/ ★過去スレ makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000 ★初心者、初級者の方は他の質問スレのほうが良いかもしれません。 例えば 【初心者歓迎】C/C++室 Ver.72【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1267775473/ とか ★教えて欲しいのではなく宿題を丸投げしたいだけなら ↓宿題スレ↓へ行ってください。 C/C++の宿題片付けます 134代目 pc12.2ch.net/test/read.cgi/tech/1263824755/ ★C++言語についてはなるべく聞かないでください。C++対応明記スレへどうぞ ★分からない事をなるべく詳しく書いて下さい。 ★ソースコードを晒すと答えやすくなるかもしれません。 # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること # サイズが大きい場合は宿題スレのアップローダ等を利用してください ★開発環境や動作環境も晒すと答えが早いかもしれません。 ★質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
2 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:30:36 ] ,.―――‐ 、 / ,.―`.ヽ / | /:/: :ィ: : : : :\ / .f⌒h/`:/l:/^\:/l:/: :|` ゲ な 〈 _! l /ムl: :/ _ '^jノ| ソ .ん _| 人_|: l ,, ̄ =l: |,_ ?. で {:::_~,.:::}」: |. 「 7 '''}!::::|__ / /.,.=、|:!:.ト . l_/ ,.ィ_└┐:|__ ( └勹ノl:| |\、 // '|!V〉\;/
3 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:42:31 ] すみません前スレのスタックフレームの者ですが、 局所変数は関数呼び出し時に、スタック領域に確保されるということでおkですよね。 局所変数の大きさはソース見ればわかる、という回答者の方もいますが 実行時にソースを読んでいるわけではないですよね。 そうするとコンパイル時に大きさを求めて、そんで実行時、スタック領域に 局所変数に必要な大きさのフレームを確保する必要があると思うのですが その大きさは、、、やはりどこから求めているのかわかりません。
4 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:43:51 ] >>3 コンパイル時に変数の個数はわかってるだろ。
5 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:46:19 ] >>3 局所変数は関数内で有限個だから、コンパイル時に種類と個数を(どうにかして)数え上げれば、スタック上に準備すべきサイズもわかります。 実行時に求めるわけではありません。コンパイル時に判明することです。
6 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:51:41 ] どうにかして数え上げればっていうか、どの型の変数が何個使われてるとか ばっちりわかってないと、コンパイルできないだろ。 C99は実行時に配列の長さを指定できるけど、べつにそういうの気にしてるわけじゃないよな。 質問者は。
7 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:52:20 ] >>5 > スタック上に準備すべきサイズもわかります。 それはコンパイル時に判明したサイズですよね。 実行時もそのサイズを知る必要があると思うのですが、どこにあるのですか。 実行バイナリファイルにあるのでしょうか。 プロセスの仮想空間にロードされた後もわかるのでしょうか。
8 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:56:32 ] >>3 スタックの大きさは決めうち コンパイルオプションで変えられる 実行時に呼ばれた関数が必要としている分だけ スタック領域を準備しようとするけど実行時に不足していればスタックオーバーフローで止まる 再帰関数で油断してたり、巨大な配列を自動変数で確保しようとしたりするとよく起こること
9 名前:5 mailto:sage [2010/03/05(金) 23:56:51 ] >>6 んー、確かにC99可変長配列の扱いはありましたね。
10 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:00:56 ] >>7 コンパイル時に自動変数に必要なサイズが判明しておれば、それにしたがってスタックポインタを変化させるコードをコンパイル時に生成すればいいのでは。 実行時にあらためて自動変数のサイズを求める必要はないはずです。仮想メモリの話は関係ないと思います。
11 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:06:08 ] >>7 homepage1.nifty.com/~sha_w/masm/model.html このページのPROC 〜 ENDPのところにスタックフレームを作ってるアセンブラのコードが あるでしょ。 add sp, 0FFFCh ;ローカル変数領域の作成 のところで、たとえば、intの変数が三つあったら、add sp, 12 ってコードが生成される。 それだけの話。
12 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:06:37 ] >>10 つまり、局所変数のサイズが300バイトだとしたら スタックポインタ = (現在の)スタックポインタ + 300バイト + その他情報の大きさ みたいな命令を、関数呼び出し毎にしているってことなのでしょうか。 質問ばかりですみません。
13 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:07:42 ] >>11 まちがえた。add sp, -12 だな。
14 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:08:26 ] >>11 なるほど。少し納得しました。 これで寝られそうです。みなさん、ありがとう。
15 名前:デフォルトの名無しさん [2010/03/06(土) 00:34:25 ] これは酷い fx.104ban.com/up/src/up13600.jpg
16 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:38:03 ] >>15 みゃくらくもなくグロ
17 名前:デフォルトの名無しさん [2010/03/06(土) 00:39:17 ] こんな板でも貼る奴いるんだな
18 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 00:44:48 ] 寝る前に見てしまった...orz
19 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 01:25:51 ] >>15 とにかくグロ注意 みゃくらくは不明だが... (誰か削除依頼したほうが良さげ)
20 名前:デフォルトの名無しさん [2010/03/06(土) 01:34:21 ] そんなもんどうでもいい
21 名前:デフォルトの名無しさん [2010/03/06(土) 01:36:47 ] 誤爆だったw すまんwwww これで許してwwwimg.f.hatena.ne.jp/images/fotolife/g/gatinko-uragazou/20080315/20080315232919.jpg
22 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 01:38:49 ] コラなんか要らんわぼけ
23 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 09:14:42 ] アセンブラを勉強すれば関数呼び出し時のスタック操作とか自分でやるから理解が深まるけどな。 しかし、なんでここまで気にするんだろ?
24 名前:デフォルトの名無しさん [2010/03/06(土) 12:13:05 ] たぶん自分独自のコンパイラ開発しようとしてるんだろ。ううんきっとそう
25 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 12:45:36 ] エラー時にスタックトレースを出力したいとか
26 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:05:44 ] >>23 ここまで気にする人だから、Cを学ぼうとしているんだろう。 低レベルに興味ない奴はVBとかJavaに行くだろ。
27 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:09:15 ] 知らなくても察しが付くことだけどな
28 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:14:13 ] そうか?それって天才じゃね?
29 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:29:55 ] 問題: 配列a[10]に対して、以下のコードと同等の結果になるコードを、gcc c言語のインラインアセンブラによるSSE3を駆使したコードで書け なお、long long型のサイズは8バイト。 4 long long a[10] = { 0x1234L, 0x5678L, 0x9012L, 0x3456L, 0x7890L, 0x1234L, 0 x5678L, 0x9012L, 0x3456L, 0x7890L }; 5 6 int i=5; 7 do{ 8 *(a+i+0) *= 0x3L; *(a+i+1) *= 0x3L; 9 i--; 10 }while( i > 0 ); という問題があったとして、答え合わせの解答集を無くしてしまったとして、答え合わせにこまってます。 ここの住人の方々は、みんな超スーパーハカーぞろいだという噂を聞きました。 どうか皆様がたのウルトラハイパー知識をくしして、この超難問の答えを導き出していただけませんでしょうか…! よろしくおねがいします。
30 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:44:53 ] 4 long long a[10] = { 0x1234L, 0x5678L, 0x9012L, 0x3456L, 0x7890L, 0x1234L, 0 x5678L, 0x9012L, 0x3456L, 0x7890L }; 5 6 int i=10; 7 do{ 8 *(a+i-0) *= 0x3L; *(a+i-1) *= 0x3L; 9 i--; i--; 10 }while( i > 0 ); すみません、こうでしたw
31 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 15:47:43 ] >>30 まだ間違ってるんじゃね?
32 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 17:00:02 ] >>29 なんでお前に命令されなきゃいけないわけ?
33 名前:デフォルトの名無しさん [2010/03/06(土) 17:23:15 ] その前にいくらよいしょしてもここにそんなに知識のある奴はいないと思うが。
34 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 17:36:02 ] おれ>>32 だけど、ちょっと頭がおかしくなってた。 ごめんな。
35 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 17:46:26 ] > 問題があったとして、 解答集を無くしてしまったとして そもそも仮定からしておかしい
36 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 19:00:29 ] つーか >インラインアセンブラによるSSE3を駆使したコード どういう頭の構造だと、これが C の質問だと思えるのかと。
37 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 19:38:27 ] /* sayHello() 関数へのポインタ */ void (*func)(void) = sayHello; このとき、'func()' と '(*func)()' の違いって何ですか? 結果は同じなのですが...
38 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 19:47:52 ] 281 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 00:27:05 関数ポインタって代入時の&と実行時の*ってなくても動作変わらないよね? もともとはどっちが正しいの? 282 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 01:06:42 元々必要だったらしいが、gccがなんか理論武装して独自拡張として省略しても良くしたら、 世間に受け入れられたなんて話を聞いたことがある。
39 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 19:49:50 ] ↑ ありがとう.
40 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 21:54:41 ] #include <stdio.h> int main () { unsigned long long a[10]={ 0x1234111111111111L, 0x5678000000000000L, 0x9012000000000000L, 0x3456000000000000L, 0x7890000000000000L, 0x1234000000000000L, 0x5678000000000000L, 0x9012000000000000L, 0x3456000000000000L, 0x7890000000000000L }; unsigned long long b[2]={3,3}; printf("3a={%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx}\n", a[0]*3,a[1]*3,a[2]*3,a[3]*3,a[4]*3,a[5]*3,a[6]*3,a[7]*3,a[8]*3,a[9]*3 ); unsigned long long* ap = a; unsigned long long* bp = b; int i=5; while(i-->0){ asm volatile ("\ movdqa (%0),%%xmm0;\ movdqa (%0),%%xmm1;\ paddq %%xmm1, %%xmm0;\ paddq %%xmm1, %%xmm0;\ movdqa %%xmm0,(%0);\ " : "+r" (ap) : "r" (bp)); ap++; ap++; } printf ("3a={%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx}\n", a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]); return(0); }
41 名前:40 mailto:sage [2010/03/06(土) 21:57:23 ] を実行したら 3a={369c333333333333,368000000000000,b036000000000000,9d02000000000000,69b0000000000000,369c000000000000,368000000000000,b036000000000000,9d02000000000000,69b0000000000000} 3a={369c333333333333,368000000000000,b036000000000000,9d02000000000000,69b0000000000000,369c000000000000,368000000000000,b036000000000000,9d02000000000000,69b0000000000000} ってなりました… 意味が分かりません… 動くはずないのに… なんで動いてるんですか…(orz
42 名前:デフォルトの名無しさん [2010/03/06(土) 22:57:36 ] WindowsNT系のコマンドをC言語で呼び出す方法を教えてください。 dirなどのコマンドを呼び出す方法を教えて欲しいです。 仮に代替できるWin32APIやC言語の関数があったとしても、dirを直接呼び出す方法を教えてください。 よろしくお願いします。(dir以外の他のコマンドも将来的に呼び出したいため) 環境はWindowsNTだけサポートしてれば大丈夫です。
43 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 23:08:33 ] systemとか winexeとか dirだけでいいならopendirとか
44 名前:デフォルトの名無しさん mailto:sage [2010/03/06(土) 23:41:00 ] _poepn
45 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 00:28:51 ] CreateProcessだろ DOS画面出さず出力をメモリに入れられる
46 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 01:03:39 ] >>45 つスレタイ
47 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 07:59:22 ] const と define の違いが今ひとつわからない どっちも定数を定義するんだよね?
48 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 08:47:35 ] ココでも読め。 detail.chiebukuro.yahoo.co.jp/qa/question_detail/q128719177 rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200510/05100021.txt
49 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:20:16 ] C言語でrailsのActiverecord 作ってくださいお願いします
50 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:23:47 ] 自分でやれよ
51 名前:デフォルトの名無しさん [2010/03/07(日) 10:37:04 ] >>47 define ・・・最も古くから使われている enum ・・・ヒゲさん曰く見えない圧力に押されて追加、いまいちらしい const ・・・禿と共同開発 定数を返す関数という手もあり これが実は最も融通が利く
52 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:55:25 ] defineはコンパイル時に置き換えてくれるだけ だからマクロとして使えるし、関数丸ごとdefineしてみるとか変なこともできる __LINE___や__TIME___みたいなコンパイル時に決まるやつもある 事項時はもうすでに置き換わっているのでaaaaとかって名前でdfineしてデバッカでaaaa探してもない constはメモリ上に固定でそいつがずっといるだけ つまりデバッカで値も見れる
53 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:55:26 ] >>47 これ↓も似たような質問かな? C言語のdefineとグローバル関数について - Yahoo!知恵袋 detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1237313677
54 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:57:16 ] おれ52だけど なんでアンダーバーが3っつなんだろ??
55 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 10:59:46 ] コンパイル時というかプリプロセス時
56 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:00:50 ] キーリピート間隔を短く設定していたんじゃないのか
57 名前:デフォルトの名無しさん [2010/03/07(日) 11:12:23 ] 8bitのデータで、 6ビット目が1になったら他のビットが1でも0でも関係なく特定の処理をする動作はどのようにすればよいでしょうか。
58 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:17:02 ] & (1 << 5)
59 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:17:36 ] if(data&0x20){ 特定の処理 }
60 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:36:45 ] ループを使わずに配列の順序を逆にせよ。 という問題は、ループ制御構造(whileやfor)を使わずに、という意味でいいのかな? 関数の再帰呼び出しでもできそうだけど、goto文使ったらだめ?
61 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:38:53 ] >>60 それはCの問題ではなく日本語の問題じゃね? どういう意図で書いたのかを書いた人に聞けよ
62 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:43:04 ] >>61 このホワイトボードプログラミングのところ: http://japan.zdnet.com/sp/feature/07tenthings/story/0,3800082984,20409456-2,00.htm 一応、こんな感じで(^^ int * reverse(int ary[]) { int i = 0; int j = SIZE - 1; int tmp; loop: if (i >= j) goto end; tmp = ary[i]; ary[i++] = ary[j]; ary[j--] = tmp; goto loop; end: return ary; }
63 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:47:31 ] gotoつかってもループだろ
64 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:49:50 ] goto文はループ制御構造ではないんですよね。 だったら「ループを使わずに」じゃなくて「再帰を使って」、と書けばいいのに。。
65 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:51:03 ] たぶん出題意図としては、再帰を使ってほしいんじゃないかね Cというよりは関数型言語でやらせるような問題
66 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 11:52:09 ] >>62 答え出てるぞ * ループを使わずに配列の順序を逆にする。 答え:順次、配列を画面に表示して行ってオペレーターにメモさせておき、 メモした値を逆順に入力するよう促すダイアログを出す。
67 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:21:02 ] 画像の範囲内をマウスのクリックで判定させるにはどのような考え方をすればよいのでしょうか? 参考サイトがあれば紹介して頂きたいです。
68 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:30:16 ] UNIX環境でVCの代わりになるような物ってないですかねぇ
69 名前:デフォルトの名無しさん [2010/03/07(日) 13:34:37 ] VC のどんな特徴の「代わり」ができればいいんだ? VC そのものなら Xen という手もある
70 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:35:53 ] >67 その画像が矩形なのか矩形以外の多角形なのかで変わる >68 Anjuta, Emacs, Geany
71 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:38:38 ] >>70 矩形を想定しています。
72 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:44:12 ] >>71 ドラッグして範囲選択みたいな感じ? 考え方っていうか、サンプルコード見たほうが早いんじゃない? マウスダウンのイベントでマウスカーソルをキャプチャして、マウスの ボタンが離されたれらそこまでが選択範囲だけど。
73 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:49:13 ] 単にヒットした座標か画素が欲しいだけだろ
74 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:53:45 ] 範囲選択ではなく、画像のスイッチのような感じです。 一定の矩形の範囲内をクリックすることで、処理が行われるようにしたいと 思っています。
75 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 13:58:16 ] ゲームでも作りたいんじゃないの 確かやねうさんはビット演算でやっていたな 自分で紙に矩形とポイントを描いて条件を考えてみれば自ずと答えが見えてくるよ
76 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 14:20:51 ] マウスの位置と矩形の位置を取得しておいて 矩形の上境界線と下境界線の間にマウスの縦座標があって 左境界線と右境界線の間にマウスの横座標があればいいだけじゃないの?
77 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 14:30:09 ] left <= x && x <= rignt && bottom <= y && y <= top
78 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 14:30:29 ] >>67 むかしBMPファイル(って予備領域とか拡張可能になってるから)に勝手にホットスポットっていうか クリック可能位置を付け足してクリックすると話が進む紙芝居、見たいなの作った 言語も環境も書いてないからあれだけど クリッカブルマップ、とかでググってみるとなんとかくやり方わかると思うよ あとは環境しだいで同じ様な事を違うやり方でやれば
79 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 14:44:28 ] 様々なご回答ありがとうございます。 全て参考にさせて頂きます。
80 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 15:18:45 ] >>68 : kdevelop (書こうとしてる字を予測して、自動補完してくれるからラクちんです) >>71 : 三角形がいっぱいあるとおもってやるほうほうもあるみたいですよ。 double OuterProduct( double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz ) { double Ax=bx-ax; double Ay=by-ay; double Az=bz-az; double Bx=cx-bx; double By=cy-by; double Bz=cz-bz; double opx = (Ay*Bz-Az*By); double opy = (Az*Bx-Ax*Bz); double opz = (Ax*By-Ay*Bx); return opz; } B A △ C 3角形ABC の中に、点P が「中かな?外かな?」ってのを知りたいときは、 「AB と P」、「BC と P」、「CA と P」 の3つについて、この関数で調べてみて、戻り値が3つとも全部プラス、または3つとも全部マイナスなら 点Pは 3角形ABCの内側ってことらしいです。 なんでか理由はよくわかりませんがw 符号1 = OutarProduct( Aのx座標、Aのy座標, 0、 Bのx座標、Bのy座標、0、 Pのx座標、Pのy座標、0 ); 符号2 = OutarProduct( Bのx座標、Bのy座標, 0、 Cのx座標、Cのy座標、0、 Pのx座標、Pのy座標、0 ); 符号3 = OutarProduct( Cのx座標、Cのy座標, 0、 Aのx座標、Aのy座標、0、 Pのx座標、Pのy座標、0 ); if( 符号1と符号2と符号3が、3つともプラス。 または3つともマイナスなら){ 点Pは、さんかっけいABCのうちがわ♪ } ってなるみたいです。 なんでか理由はよくわかりませんがw こんど算数の先生に聞いてみまーす。
81 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 15:22:25 ] 外積で左右判定してるんでしょ
82 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 16:35:50 ] >>67 三角形の内部の点かどうか判定するプログラム #include<stdio.h> #include<math.h> int is_inner(double ax, double ay, double bx, double by, double cx, double cy, double px, double py) { double Ax, Ay, Bx, By, Px, Py, alpha, beta, divisor; Ax=ax-cx; Ay=ay-cy; Bx=bx-cx; By=by-cy; Px=px-cx; Py=py-cy; divisor=Ax*By-Bx*Ay; if(fabs(divisor)<1.0e-6) return 0; alpha=(By*Px-Bx*Py)/divisor; beta=(-Ay*Px+Ax*Py)/divisor; if(0.0<alpha && alpha<1.0 && 0.0<beta && beta<(1.0-alpha)) return 1; return 0; } int main(void) { printf("%d\n", is_inner(1.0, 2.0, 2.0, 1.0, 1.0, 1.0, 0.5, 0.499)); return 0; }
83 名前:デフォルトの名無しさん [2010/03/07(日) 21:51:15 ] 再帰的アルゴリズムの利便性がわかりません。 下手をすればスタック領域が蓄積されていってメモリ不足に陥りますよね。 再帰を使わなくても他に解決できる手段があればみなさんはどちらを選択しますか
84 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 21:54:10 ] >>83 間違いが少ないほう
85 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 21:56:59 ] ほらループなしで処理が書けたよ!と頭よさげにアピールできる 問題領域そのものが再帰的なら可読性と保守性があがる C言語ではあまり利点がないので他の手段で頑張る 関数型言語とかだとまた別の話しになる
86 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:10:59 ] >>83 利便性っていうか、再帰的な処理は再帰で書いた方がわかりやすいな。
87 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:11:17 ] 関数に状態を持たせるのがどうじゃこうじゃ 逆に再帰で書いているのを繰り返し制御などで書き直す方が頭良さげ 最近再帰使ったのはビット単位でファイルに書き込む関数の下請け関数だわ
88 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:28:25 ] 本物のプログラマは自己書き換えプログラミング・コードを記述する。 そのことにより再帰アルゴリズムを使うのに比べて20ナノ秒も実行時間が改善される どうしても再帰なんつう場面は数年に一度 それ以外は、再帰アルゴリズムがぱっとわからないと馬鹿にされるという理由だけで使用する プログラマってそんなもん
89 名前:デフォルトの名無しさん [2010/03/07(日) 22:52:19 ] 再帰は、数学の階乗を求めるプログラムをかじった程度です。 可読・保守性があがるという利点は納得です。 逆にプログラマが再帰プログラムを創り出すほうが大変そう。 階乗求める以外に再帰を使ったほうがいいケースは思いつきにくいですね
90 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:53:10 ] >>89 3D オブジェクトを扱うときは必須だよ
91 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 22:54:05 ] 階乗こそ単純ループで十分で再帰にする必要なんてないんだが。
92 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:00:41 ] 無向グラフの経路探索とか再帰使わないと面倒でやってられんけど
93 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:01:26 ] >>89 ディレクトリをおりていく処理とか、ループで書くとめんどくさいだろ。
94 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:12:27 ] >>91 教材的な意味だろ
95 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:46:11 ] 教材としてあげるにしても、せめてユークリッドの互除法とか、フェボナチ数列(など漸化式)とかが出てこないものか
96 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:47:17 ] 再帰関数の教材ならハノイの塔の問題を解く奴が好き
97 名前:デフォルトの名無しさん mailto:sage [2010/03/07(日) 23:56:03 ] 他人のコードで見つけるとループに書き換えられないかと難癖付けてみたくなる要素 自コードと同じスタックでライブラリ的利用させてもらう場合特に
98 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 00:55:01 ] 組み込み系だと、変数を取れるキャパが決まってたりして 「お、スタックが空いてる再帰でなんとかしろ」とかあるよ
99 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 01:18:44 ] >>89 再帰だとシンプルに書けるものはたくさんある。 もちろんスタックオーバーフローには注意が必要だけど、 プログラマの差ってのはこういうところから来るんだと思う。 例えば、テキストファイルの行を逆順に出力する(いわゆるtacコマンド) を作ろうとすると、再帰だとこんなにシンプル #include <stdio.h> void rev() { char buf[1000]; if(fgets(buf, 1000, stdin) != 0) { rev(); fputs(buf,stdout); } } main() { rev(); }
100 名前:デフォルトの名無しさん mailto:sage [2010/03/08(月) 01:21:16 ] >>99 再帰関数で大きな自動変数の配列を使うのはナシだろ