[過去ログ] 【初心者歓迎】C/C++室 Ver.100【環境依存OK】 [無断転載禁止]©2ch.net (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
28
(1): デフォルトの名無しさん [sage] 2016/11/08(火) 15:38:54.44 ID:FW358liz(1/3) AAS
using std;
int main() {
int a;
cout<< "数を入力してください" <<endl;
cin>> a;
cout<<a <<"ですね?" <<endl;
}
aを確実に入力させたくて困っています
ご教授ねがいます
29: デフォルトの名無しさん [sage] 2016/11/08(火) 16:03:34.41 ID:j/2yZvJO(1) AAS
まず確実ってなんやねん
数以外だったり未入力は弾くってか
30: デフォルトの名無しさん [sage] 2016/11/08(火) 16:26:08.25 ID:FW358liz(2/3) AAS
そうです
未入力で無限ループみたいに表示されて困っています
31: デフォルトの名無しさん [sage] 2016/11/08(火) 16:26:29.50 ID:Or+T0geg(1) AAS
教示ならしてやっても良いが、教授はお断りだ
32
(1): デフォルトの名無しさん [sage] 2016/11/08(火) 16:58:49.59 ID:sBMnjDSh(1) AAS
>>28
外部リンク:ideone.com

一応単なる改行や数字で始まらない文字列は弾くようにした
ただしコメントにも書いてあるけど 123def みたいな数字で始まる文字列を
入力したときは数字だけ返すんでそれが駄目なら自前で作るしかないね
33: デフォルトの名無しさん [sage] 2016/11/08(火) 17:22:56.70 ID:FW358liz(3/3) AAS
>>32
getline知りませんでしたが何とかできそうです
ありがとうございます
34
(3): デフォルトの名無しさん [sage] 2016/11/10(木) 10:52:07.29 ID:8ULjF/bN(1/8) AAS
独習C第4版 P197ページの再帰のプログラムなのですが、
#include <stdio.h>

void recurse(int i);

int main(void)
{
recurse(0);

return 0;
}

void recurse(int i)
{
if(i < 10) {
recurse(i + 1);
printf("%d " , i);
}
}

実行結果は
9 8 7 6 5 4 3 2 1 0

の動作がわかりません。10になるまでprintfが実行されずに+1され続けるのはいいのですが、
なぜ10になったらiが戻り始めるのでしょうか?
あまりに初心者な質問ですみません。
35
(2): デフォルトの名無しさん [sage] 2016/11/10(木) 11:03:28.04 ID:6ImFpJhK(1/3) AAS
引数だけ書くと
0+1
1+1
・・・
9+1
ここまではprintfまで来ないまま再帰
9+1でifに入らないからrecurseからリターン
printfがiを表示(9)してリターン
printfがiを表示(8)してリターン
の繰り返し
36
(1): 34 [sage] 2016/11/10(木) 11:07:42.28 ID:8ULjF/bN(2/8) AAS
>>35
早速のレスありがとうございます。

>9+1でifに入らないからrecurseからリターン
ということはmain関数のreturn 0でプログラムは終了してしまうのではないですか?
なぜprintfが呼ばれるのかわからんのですが。(iが減算される理由もわかりません)
37
(2): 34 [sage] 2016/11/10(木) 11:12:33.48 ID:8ULjF/bN(3/8) AAS
if(i < 10) {
recurse(i + 1);
printf("%d " , i);
}

recurseとprintfは同じifブロックに入っているので、ifが偽なら両方共スキップされると思うのですが、
なぜprintfだけ呼ばれるのでしょうか?
38
(1): デフォルトの名無しさん [sage] 2016/11/10(木) 11:20:27.66 ID:69ogPHI/(1/4) AAS
丁度再帰打ち切り付近の挙動

i=8 で受けた recurse
 recurse(8+1) の呼び出し
 i=9 で受けた recurse
  recurse(9+1) の呼び出し
    i=10 で受けた recurse
    条件合致せず戻る
 printf("%d", i) で 引数の 9 を書く
 i=9 で受けた recurse から戻る
printf("%d", i) で 引数の 8 を書く
i=8 で受けた recurse から戻る
39
(1): デフォルトの名無しさん [sage] 2016/11/10(木) 11:28:04.25 ID:6ImFpJhK(2/3) AAS
>>37
9+1で入って偽で抜けたら
8+1で入ってきたif内のrecurseから抜けて次のprintfが実行されて抜ける
8+1で抜けたら7+1で入ってきたif内のrecurseから抜けて次のprintfが実行される
の繰り返し
40
(2): 34 [sage] 2016/11/10(木) 11:40:24.95 ID:8ULjF/bN(4/8) AAS
>>35-39さん
どうも再帰関数とforループがごっちゃになっていたようです。
何となくわかりました。
後は自分で考えてみます。
どうもありがとうございました。
41
(1): デフォルトの名無しさん [sage] 2016/11/10(木) 12:42:30.91 ID:69ogPHI/(2/4) AAS
再帰呼び出し後に書く  recurse(i+1); printf("%d ", i);

書いてから再帰呼び出し printf("%d ", i); recurse(i+1);
の違いとか

呼び出しの出入りを整理する
printf("in:%d\n", i);
recurse(i+1);
printf("out:%d\n", i);
と見えてくると思うよ
42
(1): デフォルトの名無しさん [sage] 2016/11/10(木) 13:57:04.04 ID:gEXUDT4B(1/5) AAS
なんか遠回りな説明ばかりだな
スタックフレームというキーワードを出してやれよ
43
(3): 40 [sage] 2016/11/10(木) 14:01:09.75 ID:8ULjF/bN(5/8) AAS
>>41
>再帰呼び出し後に書く  recurse(i+1); printf("%d ", i);
>と
>書いてから再帰呼び出し printf("%d ", i); recurse(i+1);
>の違いとか

これはこの本の次のページにも書いてありました。
書いてから再帰呼び出しの場合は昇順(1,2,3,4,5,6~)になりますね。

相変わらず曖昧な理解なんですが、
どのiの場合もi=10に達するまではrecurse(i+9)までしか実行されていなくて、
printfは実行されていない待機中の状態だと考えればいいのでしょうか?
それでi=10でif条件文を抜けて、i=9からi=0まで数字が大きい方から順番にまだ実行していなかった
printfを降順で実行していくのでしょうか?

この本(独習C)には
> 引数の値が10に達すると、recurse()の再帰呼び出しから戻りはじめます。関数は、呼び出し元に戻る
>ものなので、recurse()は直前の呼び出し元に戻り、そこでprinf()を文を実行して「9」と表示し、
>さらに前の呼び出し元に戻ります。こうしてrecurse()は、今度は「8」と表示します。 その後も同じ>プロセスが繰り返され、すべての呼び出しから戻った段階でプログラムが終了します。

実行される順番が、最初のi=0からではなく、直近のi=9からなのはなぜなのでしょうか?
44: デフォルトの名無しさん [sage] 2016/11/10(木) 14:02:24.39 ID:69ogPHI/(3/4) AAS
再帰でどう動いてるか理解するのに
スタックフレーム出されても困らないか? 値の保持の実装でそうなってるってだけだし
45: デフォルトの名無しさん [sage] 2016/11/10(木) 14:09:10.79 ID:gEXUDT4B(2/5) AAS
この手の人は、具体的な実装例を見さえすれば、すぐさま疑問が解消されるんだよ
>>43でも「待機する」だとか
なんで逆順になるのか分からないとか
言っているが
スタックフレームさえ知れば全ての疑問は解決だし
C/C++するのにスタックフレームさえ知らない状態だと
このさき困難だろう
46: デフォルトの名無しさん [sage] 2016/11/10(木) 14:10:50.73 ID:69ogPHI/(4/4) AAS
おっけー まかせた
47: デフォルトの名無しさん [sage] 2016/11/10(木) 14:18:39.78 ID:gEXUDT4B(3/5) AAS
待機する、って言い方を見るに、何かキューのような物を連想しているようだし
実際、なんで逆順になるか分からないと発言しているわけだが
答えは関数呼び出しはキューではなくスタックだから、と言う他ない
キューやスタックという言葉の意味が分からなかったとしても
どのみちこれらも覚える必要のある最も基本的な事の一つだから
合わせて覚えればよいだろう
コンピュータの基本動作もよくわからないままプログラムを書くということは
多言語ではあり得るのかもしれんが、とりわけここはC/C++スレだからね
48: デフォルトの名無しさん [sage] 2016/11/10(木) 14:26:03.17 ID:gEXUDT4B(4/5) AAS
いや、俺は別に何も説明するつもりはないよ
ただ、スタックフレームというキーワードをだね
そうすれば後は本人が検索するなりなんなり、勝手に調べるだろう
キーワードが分からなきゃ検索も出来ないから、キーワードを出してやれという話
スタックを知らずして再起呼び出しの動作を理解するのは非常に困難というか
質問者は関数呼び出しがキューのようなものであると考えている可能性が高いようだけど
実際にはスタック動作だよ、と
ここを勘違いしていたら、答えにたどりつかないかなぁと
49: デフォルトの名無しさん [sage] 2016/11/10(木) 14:29:55.54 ID:6ImFpJhK(3/3) AAS
>>42
最短の説明で教えてあげてくれ任せた
50: 40 [sage] 2016/11/10(木) 14:33:22.38 ID:8ULjF/bN(6/8) AAS
スタックフレームで検索して見たところ、
外部リンク[html]:brain.cc.kogakuin.ac.jp
このページが一番わかりやすそうです。
LIFOなんで新しい関数と引数が上の方に積み上がっていくと考えれば良いのでしょうか?
first outなんで実効は新しい順(つまり今回の例の場合はi=9)ということですね。

スタックフレームという言葉で検索したらおもしろそうなサイトがたくさん出てきました。
皆さん今回はありがとうございました。
51
(1): デフォルトの名無しさん [sage] 2016/11/10(木) 14:51:19.03 ID:IzCfpVGN(1) AAS
>>43
まず大前提としてプログラムの流れは1本道で別れたりしないし、待機みたいなことも普通しない

そして再帰関数という特別な関数があるわけではない、recurseは普通の関数と何も変わらない

void recurse(int i)
{
if(i < 10) {
recurse(i + 1);
printf("%d " , i);
}
}

この4行目はrecurseという関数を呼び出している
つまり自分自身を呼ぶのでこの4行目の呼び出し後、recurse関数の最初に戻る
ただし引数iは1大きい値で呼ぶ
これを入れ子のように10回繰り返すことになる
52
(1): 43 [sage] 2016/11/10(木) 15:05:17.38 ID:8ULjF/bN(7/8) AAS
>>51
レスありがとうございます。
外部リンク:ipa-zone.info
このページに私が使っている独習Cの再帰の部分が丸ごと転載されているんですが(違法?)、

i=0~10と昇順で増加していく前半部分でも呼び出された関数(recurse(1)など)は終了した訳ではないですよね?
後半のi=10から降順で減少していくときにはじめてprintfが実行されて関数が終了すると思うんですが、
LIFOなんで最後に呼び出されたrecurse(9)からrecurese(0)まで降順で残ったprintfを実行していくということではないんですか?
1-
あと 950 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.020s