■プログラムは後半に書いてます。よろしくお願いします。
no x y
―――――――
10行目 3 1 3
10行目 2 1 2
10行目 1 1 3
printf
■この後の5回(できれば10回)の進み方を教え貰えると嬉しいです。
■わからない理由
printfのとき、(no, x, y) = (1, 1, 3)でno = 1。
そのため13行目は行われない。
しかし、returnもbreakもないためまた6行目に戻るのでしょうか?(答えを見ると6行目に行きそうです。)
(no, x, y) はどのような値で関数が始まるのでしょうか?
9行目があるのにno=2or3で表示される理由がわからないです。
01|#include <stdio.h>
02|#include <conio.h>
03|
04|#define N 3
05|
06|void move(int no,int x,int y)
07|{
08|static int i=1;
09|if(no>1)
10|move(no-1,x,6-x-y);
11|printf("%dを%d軸から%d軸へ移動 : %d\n",no,x,y,i++);
12|if(no>1)
13|move(no-1,6-x-y,y);
14|}
15|
16|int main(void)
17|{
18|move(N,1,3);
19|
20|_getch();
21|return(0);
22|}
No.3ベストアンサー
- 回答日時:
再帰を考えるときに「10行目 に行くと n > 1 で6行目に戻りますよね?」と思っちゃダメです. #2 に書いてある「別の move」の意味を読み取ってください.
分かりやすいかどうか知らんしあんまり適切って感じもしないけど, こんな風に考えることもできます:
最初に main から呼び出される move を move0, move0 から呼び出される関数を move1, ... としてみてください. つまり
void move1(int no,int x,int y) /* (b) */
{
static int i=1;
if(no>1)
move2(no-1,x,6-x-y);
printf("%dを%d軸から%d軸へ移動 : %d\n",no,x,y,i++);
if(no>1)
move2(no-1,6-x-y,y);
}
void move0(int no,int x,int y) /* (b') */
{
static int i=1;
if(no>1)
move1(no-1,x,6-x-y); /* (a) */
printf("%dを%d軸から%d軸へ移動 : %d\n",no,x,y,i++);
if(no>1)
move1(no-1,6-x-y,y);
}
int main(void)
{
move0(N, 1, 3);
/* 以下略 */
}
のような感じです. このとき, (a) の関数呼び出しによって (b) と (b') のどちらに行くと思いますか?
「再帰呼び出し」というのは, 同じ関数を「改めて呼び出す」ということです. 間違っても「関数の先頭に戻る」という意味ではありません.
ありがとうございます。
同じ奴では無いということですね!
一段目のmove1
その次に二段目のmove1
そして三段目のmove1に・・・
なんとなく再帰理解することが出来ました。ありがとうございます。
No.2
- 回答日時:
これは、「再帰」と呼ばれる方法です。
関数内で自分自身を呼びだします。
moveの動作は次の通りです。
9,10行目:n>1ならmove(no-1,x,6-x-y);を呼び出す
11行目:printf
12,13行目:n>1ならもmove(no-1,6-x-y,y);を呼び出す
14行目:関数の終りなのでreturn
10行目 3 1 3
10行目 2 1 2
10行目 1 1 3
printf
とありますが、10行目でループしているのではなく、
3 1 3 mainの中からmove(3,1,3)で呼び出したもの
2 1 2 ↑のmoveの10行目で move(2,1,2)で呼び出したもの
1 1 3 ↑のmoveの10行目で move(1,1,3)で呼び出したもの
printf ↑で呼び出されたmove(1,1,3)はn=1なので、もう別のmoveは呼び出さない
と、 moveの中からmoveを呼び出したものです。
> しかし、returnもbreakもないためまた6行目に戻るのでしょうか?
戻りません。
途中で「別のmove」を実行しているので、6行目に戻っているように見えるだけです。
関数の最後まできたら自動的にreturnする、というのがCの動作です。
> (no, x, y) はどのような値で関数が始まるのでしょうか?
どこから呼ばれるかは、順番に辿ればわかります。
実行して最初に呼ばれるのはmain関数です。
その中に move(N,1,3); とあるので、これが最初です。
> 9行目があるのにno=2or3で表示される理由がわからないです。
if(no>1)
move(no-1,x,6-x-y);
ですが、 {}が無いですよね? これは、ifの直後の ; までが{}に入っているのと同じことです。
if(no>1) {
move(no-1,x,6-x-y);
}
どちらも正しい文法です。前者は初心者にはまぎらわしいので、{}を必ず付けるようにするとよいでしょう。
で、こうすると、printfには何も条件が付いていないことがわかります。
この回答への補足
■素早い返答ありがとうございますm(_ _)m
■関数の最後まできたら自動的にreturnする、というのがCの動作です。
知りませんでした!ありがとうございます!
■まだ分からない所が・・・時間があればもう一度よろしくお願いします。
10行目 に行くと n > 1 で6行目に戻りますよね?
そうするとまた10行目・・・
となり結局11行目のprintfへたどり着くときは n = 1 以外ないような気がします。
11行目 に行けたということは n = 1 と言うことで…、そうすると 12行目 の条件式の存在意味が…ない?
本当に 12行目 の式は正しいんでしょうか?
PS この問題と課題は「解きながら学ぶC言語」に掲載されていた例題です。
No.1
- 回答日時:
返り値が void であるような関数では, 最後の } にたどりついたら「return; が書かれている」ものとして処理されます.
これで「returnもbreakもないため」という疑問は完全に解消されましたね.
この回答への補足
返り値が void であるような関数だと「return; が書かれている」ものとして処理されるんですね!
理由を知れる方が記憶に残るので・・・ありがとうございます!
よければ上の補足質問よろしくお願いしますm(_ _)m
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# c言語 5 2023/04/27 13:20
- C言語・C++・C# プログラミングペーパーテスト 次の問題の実行結果を答えろ #include int x[ ] = { 1 2022/06/16 21:49
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
比較回数と交換回数表示について
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
std::set<int> で、ある値が何...
-
C言語で三目並べをするプログラ...
-
商と剰余を同時に求める(C言語)
-
if と配列の組み合わせ
-
【C++】関数ポインタの使い方
-
並列プログラミングのπ計算につ...
-
c言語
-
HANDLEて何ですか?
-
read関数をノンブロッキングで...
-
卒業研究でよく分からないとこ...
-
DLLをGetProcAddress()で実行で...
-
GlobalAllocの変数を関数に引き...
-
シグマ公式・・・C言語
-
ファイルから読みこむ方法
-
c言語の問題です
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報