[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 2chのread.cgiへ]
Update time : 06/01 04:04 / Filesize : 158 KB / Number-of Response : 656
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

なぜポインタで引っかかる人が多いのか



1 名前:デフォルトの名無しさん [2010/06/30(水) 10:22:47 ]
なぜポインタで引っかかる人が多いのか

引っかかる人は何に困惑しているのか


508 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 18:19:53 ]
>>507
>>506 では、2分木に対するデータの追加を扱っていますが、
ポインタのポインタをつかわなければ、
struct node *root;
root = add_node(root, data);
という形になり、これでは再帰が深くなると無駄な代入が繰り返されてしまいます。
本当に代入が必要なのはデータの追加が行われたところのノードですから、そのようにコードをかいて、
sturcut node *root;
add_node(&root, data)
という形にするのが本当だと思います。
参照を使うと、
struct node *root;
add_node(root, data)
とかけますし、add_node() 自体の記述でも、* や & を省くことができます。
具体的なコードの記述例は >>504 のリンク先を参照してください。

509 名前:499 mailto:sage [2010/08/29(日) 18:27:00 ]
>>508
>ポインタのポインタをつかわなければ、
>struct node *root;
>root = add_node(root, data);
>という形になり、これでは再帰が深くなると無駄な代入が繰り返されてしまいます。
それはロジックが悪い。
そんなに代入を繰り返さなくても出来る。考えてみ。

>参照を使うと、(略)* や & を省くことができます。
参照でコードが短くなるのは当然だが、同時に、「値が変化している」という情報も失われる。
以下のような例がありえる。
struct HOGE* hoge;
func1(hoge);
func2(hoge); //ここで内容をいじっている!
func3(hoge);
これは以下のようにしたほうが「中で何かしている」感じがわかりやすくなる。
func1(hoge);
func2(&hoge);
func3(hoge);
値を変える参照は、短くなるからと無闇に使うと危険ですよ。

510 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 18:31:38 ]
>>509
>それはロジックが悪い。
>そんなに代入を繰り返さなくても出来る。考えてみ。
いや、二分木や線形リストに関しては、ポインタのポインタを使わない限り、無駄な代入が繰り返されてしまいます。
ポインタのポインタを使わずにスマートな方法があるというのなら、それは是非知りたいところです。実例を示してください。

>値を変える参照は、短くなるからと無闇に使うと危険ですよ
それはそうですね。後から読むときにわかりにくいのは事実です。

511 名前:499 mailto:sage [2010/08/29(日) 18:34:27 ]
「参照を理解してない人」に教えてもらってどうすんだ?あ?

無礼な言葉を吐くだけ吐いて、出来ないとなったら教えてください、かよ。おめでたいガキだな。

512 名前: ◆QZaw55cn4c mailto:sage [2010/08/29(日) 18:41:58 ]
>>511
コードを示してください。
私はすでにポインタのポインタを使ったもの、参照をつかったもの、ポインタのポインタを使っていないものの3種を示しています。
時間はたっぷりありますから、アイディアだけでも示してください。

話はそれから。

513 名前:499 mailto:sage [2010/08/29(日) 18:43:48 ]
バカバカしい。
無礼者に使う時間などないよ。
おまえよりもうちょっとマシな誰かが、気が向いたらコード書いてくれるかもしれないから、それまで待ってれば?

514 名前: ◆QZaw55cn4c mailto:sage [2010/08/29(日) 18:47:43 ]
>>513
よく検討もせずに
>それはロジックが悪い。
というほうがよっぽど無礼ですね。こちらは動くコードを書いた上で意見を述べているのですけれども。

コードを示してください。
話はそれから。

515 名前:499 mailto:sage [2010/08/29(日) 18:50:23 ]
そこのロジックの悪さはきちんと検討して発言してるよ。
代替コードも書いている。
おまえにタダで見せる気にならないだけだ。
誰か奇特な人が見せてくれるまで口あけて待っとけ。

516 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 20:34:55 ]
>>515
何か既視感があるな・・・



517 名前: ◆QZaw55cn4c mailto:sage [2010/08/29(日) 20:34:56 ]
>>515
口だけなら「コードを書いている」といくらでもいえます。

それに「見せるきにならない」といいますが、
仮に見せていただければ、私はただただ低頭して「私が馬鹿でした」と発言して消えるでしょう。
それはあなたにとっては、大満足なのではないですか

動くコードを見せて実証することで、私の今までの発言を全否定できるにもかかわらず、それをせずにうそぶくのみ。
これでは、実証するアイディアなりコードなりがないと推測せざるをえません。推測ですけれどもね。

コードを示してください。
話はそれから。

518 名前:499 mailto:sage [2010/08/29(日) 20:38:25 ]
>>517
おまえが馬鹿(というよりは、低レベル)なことは、俺にとってははっきりしてるからな。
別にこんな便所のラクガキの場所で示す必要も無い。
逆に、示してやればおまえのレベルを引き上げてしまう。バカバカしい。
ど素人はど素人のまま、学生の宿題でもやってるのがお似合いだよ。

だいたい、教えて欲しいなら、最初の暴言を謝るのが順序だろう。それもせずにただ出せなんて図々しい。

519 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 20:41:44 ]
ポインタのポインタなんて、Win32のCOMみたいな使い方をする程度かな

ふつーに
struct data *alloc_root(void);
int add_data(struct data *root, char *name, char *tel);
とか作る

520 名前: ◆QZaw55cn4c mailto:sage [2010/08/29(日) 21:22:48 ]
>>518
ひとつ可能性があるとすれば、非再帰的に記述することですかね。

線形リストならば、それは可能ですが、2分木だと結構むずかしくなります。たぶん各ノードにワークエリアを設けて
戻るノードを記憶しなければならないでしょうね。
昔書いた非再帰的なコードをあげておきます。ポインタのポインタは使っていますが。
codepad.org/n3raxalm

私は再帰的なアルゴリズムのみしか念頭にありませんでした。
もし非再帰的に記述することを示唆しておれば、大変失礼いたしまた。

521 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 21:27:33 ]
binary treeで戻る?

522 名前:デフォルトの名無しさん mailto:sage [2010/08/29(日) 21:31:53 ]
>>521
ええ、binary tree でノードの追加なり総なめを行うのなら、親ノードの位置を逐一記録しておかなければならないでしょうね。
ノードを追加したら、追加されて新しく親ノードになったところをなんらかの形で覚えておかないといけないでしょう。
もしかすると、ノードごとにワークを持つ必要はないかもしれませんが。(>>520 はノードごとにワークをもっていました。)

523 名前:デフォルトの名無しさん mailto:sage [2010/09/01(水) 22:08:27 ]
親ノードとかいらねーよアホ
バイナリツリーでそんな実装するわけねーだろ

524 名前:デフォルトの名無しさん mailto:sage [2010/09/01(水) 23:05:14 ]
たしかに非再帰に書くのなら、いらないみたいですね。
hibari.2ch.net/test/read.cgi/tech/1280653311/735

525 名前:デフォルトの名無しさん mailto:sage [2010/09/04(土) 03:15:33 ]
char *name[]ってどういう意味なんでしょうか?

526 名前:デフォルトの名無しさん mailto:sage [2010/09/04(土) 07:12:23 ]
char **name;



527 名前:デフォルトの名無しさん mailto:sage [2010/09/04(土) 10:47:37 ]
>>526
ありがとう!

528 名前:デフォルトの名無しさん mailto:sage [2010/09/04(土) 15:28:58 ]
えっ

529 名前:デフォルトの名無しさん mailto:sage [2010/09/10(金) 19:18:42 ]
アセンブラでメモリの番地は理解していても
C言語での書き方で悩む事もあるんだよ

>>55みたいな

530 名前:デフォルトの名無しさん mailto:sage [2010/09/10(金) 19:19:32 ]
constの位置とかもな

531 名前:デフォルトの名無しさん mailto:sage [2010/09/10(金) 19:53:48 ]
面倒なので括弧を付ける

532 名前:デフォルトの名無しさん mailto:sage [2010/09/10(金) 23:54:01 ]
>>530
const は一番近い場所にある token が変更不可能になる
っていう理解で桶?

533 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 00:09:14 ]
int const *
近いってどっちだよ、ってなるぞ

534 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 17:57:59 ]
暗記したほうがマシ、というか十分。
理屈を抜きにするから応用利かないけど。

この二つ暗記な。

int *p[] ポインタの配列
int *const p コンストポインタ

だからこそ、
配列のポインタが (*p)[] だと想像できるし、
コンストintへのポインタが int const *だと分かる。

535 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 18:44:36 ]
そんなにむずかしくないだろ
constが後置修飾になってるほうがポインタそのものをconstにしてるだけ
int const もconst int も int を定数にしてるだけなんだし

536 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 20:25:13 ]
いや
いまは
int const * p;

int * const p;
の違いの話をしているんじゃまいか



537 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 20:41:58 ]
イメージ的には、
ポインタの配列は(*p)[] これだし、
constポインタはconst (int *)pこう書きたい。
イメージどおりには行かんね。

538 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 20:52:42 ]
>ポインタの配列は(*p)[] これだし、

hds

539 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 21:44:43 ]
const int *p

540 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 21:54:39 ]
const int *p;
int const *p;
int * const p;

541 名前:デフォルトの名無しさん mailto:sage [2010/09/11(土) 22:22:42 ]
de?

542 名前:デフォルトの名無しさん mailto:sage [2010/09/12(日) 16:15:02 ]
掛け算以外のアスタリスクがあまり出てこないプログラムを心がけてますよ

543 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 18:36:27 ]
>>542
それは C の最強の武器を放棄したに等しい。

544 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 19:10:55 ]
>>540
kwsk

545 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:12:37 ]
const int *p => const int の ポインタ
int const *p => const int の ポインタ
int * const p => int の const ポインタ

546 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:19:34 ]
1行目と2行目の違いが判らんのだが



547 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:24:15 ]
違いはない

548 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:29:20 ]
えっ

549 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:36:05 ]
int main() {
int i = 100, j = 200;
const int *a, *b; // const int
int const *c, *d; // const int
int *const e = &i, *const f = &i; // intへのconstポインタ
int const *const g = &i, *const h = &i; // const intへのconstポインタ

*a = j; // error: assignment of read-only location
*b = j; // error: assignment of read-only location
*c = j; // error: assignment of read-only location
*d = j; // error: assignment of read-only location

e = &j; // error: assignment of read-only variable `e'
f = &j; // error: assignment of read-only variable `f'

*g = j; // error: assignment of read-only location
*h = j; // error: assignment of read-only location
g = &j; // error: assignment of read-only variable `g'
h = &j; // error: assignment of read-only variable `h'

return 0;
}


550 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:38:02 ]
ちょい修正:

const int *a, *b; // const intへのポインタ
int const *c, *d; // const intへのポインタ

551 名前:デフォルトの名無しさん mailto:sage [2010/09/13(月) 20:51:05 ]
えっえっ

552 名前:デフォルトの名無しさん mailto:sage [2010/09/14(火) 08:42:30 ]
* の左側に const があるか右側にあるかだけですべてが決まるんだよ
* が複数ある場合も何番目の * と * の間に const があるかで意味が決まる

553 名前:デフォルトの名無しさん mailto:sage [2010/09/14(火) 17:48:16 ]
難しいのー

554 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 00:05:24 ]
far * near * とかに比べると、ああらくちんだ〜。

555 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 00:11:29 ]
>>522
巡回するなら普通はスタック使うだろ?
ってマジレスしたらいかんかったのだろうか

>>523
仕様によってはあり得る

556 名前:522 mailto:sage [2010/09/15(水) 00:28:58 ]
>>555
この問題、宿題スレの方で実際にコードを書いていただき、戻る位置をおぼえない方法を示していただきました。
すぱっと非再帰に書き下すきれいなコードでした。>>524
でも、二分木は再帰で書きたいもの、とちょっと負け惜しみ。



557 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 00:46:28 ]
スタティックな変数を使えば再帰でも書ける
最適化を考えると大概再帰よりループ展開の方が速い
どっちでも書けるようになったほうがいいぞ

558 名前:522 mailto:sage [2010/09/15(水) 00:50:29 ]
>>557
それもそうですね。精進します。

559 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 13:06:41 ]
だから言ったじゃねえかよ。
あと、再帰でも、無駄なコピーなしに実装できる。
絶対できないとか頑張ってないで、ちょっと考えてみ。

560 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 13:48:49 ]
学生だと思うけど若い割に頭硬そうだよな
アルゴリズム関係は向いてないんじゃないかね

561 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 18:12:27 ]
>>559
二重ポインタか参照を使わないと無理ではないでしょうか?

562 名前:デフォルトの名無しさん mailto:sage [2010/09/15(水) 19:54:07 ]
出来るって言ってんのにわからんガキだな〜
人を疑う前に少しは考えろよ

563 名前:デフォルトの名無しさん mailto:sage [2010/09/20(月) 13:34:24 ]
>>552
嘘書くなよ

564 名前:デフォルトの名無しさん mailto:sage [2010/09/21(火) 07:13:43 ]
嘘ってこともないだろ。判り難い説明ではあるが。

565 名前:デフォルトの名無しさん mailto:sage [2010/09/27(月) 23:59:03 ]
面倒だから型の左側以外に const 使うなよ。
const int* a とかにしとけ。
int const *aとか使わんだろ。

566 名前:デフォルトの名無しさん mailto:sage [2010/09/28(火) 00:29:20 ]
int * const a



567 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 17:10:52 ]
const int const *a;

568 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 17:52:31 ]
>>567
勉強しなおそうね

569 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 17:58:19 ]
>>567
int const * const a;
or
const int * const a;

570 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 18:31:19 ]
>>569
上と下はどうちがうの?

571 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 18:57:08 ]
>>570
かわらない。

572 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 19:17:28 ]
えっ

573 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 19:22:55 ]
>568
修飾子が被っているが無視されるので問題ない
まぁ、書いた人はそんなこと意図していなかっただろうけど

574 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 19:25:25 ]
>>571
どっちが正しいっていうか一般的っていうか

575 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 20:27:37 ]
どっちも正しい

576 名前:デフォルトの名無しさん mailto:sage [2010/10/24(日) 18:26:18 ]
const int const * const a;



577 名前:デフォルトの名無しさん mailto:sage [2010/10/24(日) 19:10:29 ]
だから被ってるって、まぁいいけどね

578 名前:デフォルトの名無しさん mailto:sage [2011/02/06(日) 02:34:02 ]
ひっかけ問題みたいだから。

579 名前:デフォルトの名無しさん [2011/02/06(日) 10:06:34 ]
>>573
被ってはいないだろ

580 名前:デフォルトの名無しさん mailto:sage [2011/02/06(日) 10:48:42 ]
>>579
○ const int
○ int const
× const int const

○ const int * const
○ int const * const
× const int const * const

○ const int *
○ inst const *
× const int const *

○ int * const

○ int *


581 名前:デフォルトの名無しさん mailto:sage [2011/02/06(日) 11:55:22 ]
>>580
> ○ const int *
> × inst const *
○ int const *
inst になってしまそうになる気持はわかる


582 名前:デフォルトの名無しさん mailto:sage [2011/02/06(日) 16:59:24 ]
int const C::* p; // Cはクラス型
C* c;
c->*p;

583 名前:デフォルトの名無しさん mailto:sage [2011/02/07(月) 11:33:10 ]
我々のポインタ。いやらしい・・・

584 名前:デフォルトの名無しさん mailto:sage [2011/02/21(月) 22:33:30.98 ]
ぬるぽ

585 名前:デフォルトの名無しさん mailto:sage [2011/02/27(日) 00:22:54.55 ]
int const * const ** const *p;
コンストintへのポインタへのコンストポインタへのポインタへのコンストポインタでOK?

586 名前:デフォルトの名無しさん mailto:sage [2011/02/27(日) 00:29:38.88 ]
間違ってるぞ



587 名前:デフォルトの名無しさん mailto:sage [2011/02/27(日) 01:21:24.77 ]
指定子に対する const 以外はすべて後方から修飾。
(指定子に限りどちらからでも修飾可能)
マンバポインタといっしょで *const で一塊と見たほうがわかりやすいね。

int *p;
int ( *func )();

int *const q = p;
int ( *const funk )() = func;

class C;
int C::* r;
int ( C::* funx )();

588 名前:デフォルトの名無しさん mailto:sage [2011/02/27(日) 21:17:19.78 ]
う〜、マンバ!!

589 名前:デフォルトの名無しさん mailto:sage [2011/03/04(金) 21:22:36.79 ]
char *abc[][3] = {
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
};
で初期化出来ますが、
*abc[][3] の配列(というか *abc[][3] を指すポインタ)は、
char **xyz[][3] = {abc, def, ...};
じゃ代入出来ないんですけど、
どう書いたら良いでしょうか?

590 名前:デフォルトの名無しさん mailto:sage [2011/03/05(土) 00:30:23.52 ]
*[][3]のポインタは、*(*[][3])ね
*abc[][3]に対して、abcは*(*)[3]ね
&abcは、*(*)[][3]ね
char *(*xyz)[3] = abc;

{abc, def, ...}は、配列とかにしたいんだろうから
char *(*xyz[])[3] = {abc, def, ...};
配列にしたいので、xyz[]になる

591 名前:デフォルトの名無しさん mailto:sage [2011/03/05(土) 00:43:58.31 ]
ありがとうございます

char *(*xyz[])[3] = {abc, def, ...};

ならいけますが

 char *(*xyz[])[3] = {
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
...
};

は無理ですよね?

592 名前:デフォルトの名無しさん mailto:sage [2011/03/05(土) 00:52:24.23 ]
char *xyz[][4][3] = {略};

{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
}
が[4][3]
""が*
その配列なので、[]
char *(xyz[])[4][3]の方がわかりやすいかな

593 名前:デフォルトの名無しさん mailto:sage [2011/03/05(土) 06:04:54.10 ]
あ、説明不足でした。すみません。
char *abc[][3] = {
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
...
...
...
};
なら縦方向に可変長に出来るのに、
 char *(*xyz[])[3] = {
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"aho", "baka", "shine"}
},
...
...
};
は無理ですよね?
ってことです。

594 名前:デフォルトの名無しさん [2011/03/05(土) 06:14:40.27 ]
馬鹿には無理

595 名前:デフォルトの名無しさん [2011/04/11(月) 21:47:20.95 ]
馬鹿ばっかだな。
**、が何示してるか分からないだろ。


596 名前:デフォルトの名無しさん mailto:sage [2011/04/12(火) 22:33:04.77 ]
>>593
二次元配列へのポインタを[]を使わないで書けるようにまずはなれ



597 名前:デフォルトの名無しさん mailto:sage [2011/04/15(金) 01:00:43.52 ]
>>71
> ">私のささやかな経験から言わせてもらうと、伝統的に大学のコンピュータ
> サイエンスのカリキュラムで教えられているもので、多くの人がうまく理解
> できないものが2つあった: ポインタと再帰だ。
> "
なんか再帰が苦手だったというか、最初ハノイの塔とかでも自分で自分を呼ぶというのが
どうもよくわからなくて苦労したが、同じ名前の関数を呼ぶと考えたらあっさり理解できたな
初心者の頃。
でもトレースするのはやっぱり苦手。

598 名前:デフォルトの名無しさん mailto:sage [2011/04/15(金) 12:01:39.81 ]
>>597
自分で自分を呼ぶと考えるからややこしいんだよ。
例えば階乗なんてこれだけだ。

自然数nの階乗とは:
nが0か1の場合、1
そうでない場合、n-1の階乗にnをかけた結果

これをCでそのまま書くだけ。
unsigned factrial(unsigned n)
{
if (n == 0 || n == 1) return 1;
return factrial(n - 1) * n;
}
ハノイの塔だろうがフィボナッチ数列だろうがツリー探索だろうがみんなこれの応用だ。
なんなら解説してもいいけど、ここではスレ違いだな。

599 名前:デフォルトの名無しさん mailto:sage [2011/04/15(金) 12:18:02.65 ]
すみません
末尾再帰は単純なループに置き換え可能だそうですが
>>598 はどうなりますか?

600 名前:デフォルトの名無しさん mailto:sage [2011/04/15(金) 13:00:03.37 ]
>>599
考え方をちょっと変える必要がある。

>自然数nの階乗とは:
>nが0か1の場合、1
>そうでない場合、n-1の階乗にnをかけた結果

ここで、n-1の階乗を返す関数の代わりにn-1の階乗にnをかけた結果を返す関数を用意する。

unsigned fact_sub(unsigned n, unsigned r)
{
if (n == 0 || n == 1) return r; // 0! * r or 1! * r
return fact_sub(n - 1, n * r); // (n-1)! * r
}

これを呼ぶように>598を書き換える。
unsigned factrial(unsigned n)
{
return fact_sub(n, 1);
}

C++なら、unsigned factrial(unsigned n, unsigned r = 1)としてしまえば一関数で済む。
尤も、こんなことするまでもなく最近のgccは>598をループに書き換えるけどね。

601 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 06:21:40.62 ]
再帰は自分自身を呼び出したとき、関数の最初に戻るのではなく
呼び出したところに関数と同じ内容のブロックがあり、
それが延々と続いてるとイメージすれば分かりやすい
それはまさにツリーと同じ構造だ

602 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 06:44:15.01 ]
なるほど、そういう馬鹿げた置き換えイメージを持っているから、実際に
再帰で書けと言っても書けない奴が多いのか、再帰のロジックを読める
くせに書けない奴が多い理由がわかった。

603 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 09:02:18.74 ]
そういう書けない人には
「まずuntilループに書き換える」
「ループ内で再代入する変数は全て引数として渡す」
って2点を教えてやれ

604 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 09:04:11.42 ]
またいつもの再帰番長か。

605 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 09:11:00.70 ]
アセンブラやらないからだよ

606 名前:デフォルトの名無しさん mailto:sage [2011/04/17(日) 21:34:44.55 ]
末尾最適化が出来る再帰と出来ない再帰があるな

例えばアッカーマン関数は末尾最適化出来ない



607 名前:デフォルトの名無しさん mailto:sage [2011/04/19(火) 01:21:52.48 ]

ttp://kmaebashi.com/programmer/pointer.html
>K&Rによれば、Cの宣言は、「変数が現われ得る式の構文を真似た(P.114)」そうである。
>しかし、本質的に全く異なるものを無理に似せようとしたため、
>結局わけのわからない構文になってしまっている。

># Cの作者Dennis Ritchieが最近開発した新しい言語 Limboは、一見
># C like だが、宣言の構文はしっかりPascal風のものに直してある...
># ずるい(^^;


608 名前:デフォルトの名無しさん mailto:sage [2011/04/19(火) 01:46:12.61 ]
変数宣言の*と、デリファレンスの*で混乱したのを思い出すわ。
同じ*だと思っていたからどうにも理解できなかったわ。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<158KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef