質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Q&A

解決済

3回答

1394閲覧

C言語 再帰を使用した関数 ループしている理由を知りたい

s_u_d

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

0グッド

0クリップ

投稿2021/02/18 01:52

前提・実現したいこと

C言語を勉強している初心者です。
再帰についての質問です。

下記のコードはintで与えられた数字を与えられた関数のみを使って表示するというコードです。
与えられた数字の出力はできるようになったのですがコードを理解できません。
関数 put_nbr 内での再帰の動作を知りたいです。

アドバイスいただけたら幸いです。
よろしくお願いします。

該当のソースコード

c

1#include <unistd.h> 2 3 4void put_nbr(int nb); 5 6int main() 7{ 8 put_nbr(1234); 9} 10 11void put_char(char c) 12{ 13 write(1, &c, 1); 14} 15 16void put_nbr(int nb) 17{ 18 19 if (nb < 0) 20 { 21 put_char('-'); 22 nb = nb * (-1); 23 } 24 if (nb > 9) 25 { 26 put_nbr(nb / 10); 27 put_nbr(nb % 10); 28 } 29 else 30 { 31 put_char(nb + '0'); 32 } 33}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YukiChan123

2021/02/18 02:07

どこの部分がどう分からないんでしょうか? 一つ一つコードの流れを追いかけていけば理解できそうですが・・・
maisumakun

2021/02/18 02:08

どこまで考えてみたのですか? まず、put_nbr(1234)を呼んだ時、条件分岐はどこに進み、どのような動作が実行されるのか、追いかけてみましたか?
s_u_d

2021/02/18 02:46 編集

言葉足らずですいません。 関数put_nbr内の下記部分 if (nb > 9) { put_nbr(nb / 10); put_nbr(nb % 10); } この処理がなぜput_char(nb + '0')のnbに1文字ずつ値を渡せているのかが理解できません。
episteme

2021/02/18 03:09 編集

そこじゃなく、else { ... } の中で put_char してます。 # put_nbr(nb % 10); ← put_nbrに引き渡す値は0~9になり、call先でelse { ... } に飛び込みます。
YukiChan123

2021/02/18 02:58

「nb%10」はnb/10の余りの数を出力します。 質問の値だと1234/10は商123余り4なので4がput_nbr(int nb)に渡されます。
s_u_d

2021/02/18 03:52

このコードだと 4,3,2,1 と順にput_nbr(int nb)に渡されて put_char(nb + '0')に 1,2,3,4 と順に渡しているということになるのですか?
episteme

2021/02/18 04:04

put_nbrに飛び込んだ時点でnbをプリントすれば確認できますよ。
guest

回答3

0

ベストアンサー

コメントつけてみた。コメントだけを読めばカラクリが理解できることを期待します。

C

1void put_nbr(int nb) 2{ 3 4 // nbが負のとき: 5 if (nb < 0) 6 { 7 put_char('-'); // '-'を書いて 8 nb = nb * (-1); // 符号を反転する(正にする) 9 } 10 // nbが一桁で収まらないなら: 11 if (nb > 9) 12 { 13 put_nbr(nb / 10); // 上位桁(たとえば456なら45)をput_nbrする(再帰:1桁減るのでいつか必ず終わる) 14 put_nbr(nb % 10); // 1の位(たとえば456なら6)をput_nbrする(再帰) 15 } 16 else // nbが一桁で収まるなら(再帰はここで終りを迎える) 17 { 18 put_char(nb + '0'); // 数値を数字に(たとえば7なら'7')変換し、プリントする 19 } 20}

投稿2021/02/18 02:13

編集2021/02/18 02:45
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_u_d

2021/02/18 05:29

ご回答ありがとうございました。 コメントまでしていただきとてもわかりやすかったです。 epistemeさんをはじめ、他の方のコメントも大いに理解に繋がりました。 ありがとうございました。
guest

0

質問に対する回答ではありませんが、質問のコードだと、
<limits.h> で定義されている INT_MIN の -2147483638 を
表示すると -0 となってしまいます。

次の修正で正しく表示できるようになります。

C

1 if (nb > 9u) { 2 put_nbr(nb / 10u); 3 put_nbr(nb % 10u); 4 }

修正方法は他にもあります。

投稿2021/02/18 06:19

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_u_d

2021/02/18 08:08

ご丁寧にありがとうございます。 intの範囲外を考慮していませんでした。 参考にさせていただきます。
kazuma-s

2021/02/18 08:25

-2147483638 は int の範囲外ではありません。
guest

0

自分自身を呼び出してる処理を再帰と名付けているだけの話で、なにも特別なことをしてるわけではないです。
簡単に考えましょう。
まずは一桁の数字を与えた場合の動作を追いかけましょう。
次に、2桁を与えた場合、
3桁を与えた場合、
を、どういう処理になるかを追いかけていけば理解できるようになります、

投稿2021/02/18 02:07

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s_u_d

2021/02/18 04:05

ご回答ありがとうございます。 おっしゃっていただいたように小さな数字から動作を考えてみると理解が深まりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問