• ベストアンサー

int rev_int(int num)文  関数の入門

#include<stdio.h> /*---非負の整数を読み込んでます*/ int scan_uint(void) //関数scan_uintは、キーボードから非負の整数値を読み込んでその値を返す関数です。 { //この関数には受け取るべき仮引数がありません。仮引数がないことを示すためには()の中をvoidとします。 int tmp;//テンプの箱作成 do { printf("非負の整数を入力してください:"); scanf("%d", &tmp); if (tmp < 0) printf("\a負の数を入力しないでください"); } while (tmp < 0); return (tmp); } /* 非負の整数を逆転した値を返す */ int rev_int(int num) { int tmp = 0; if (num > 0){ do { tmp = tmp * 10 + num % 10; num /= 10; }while (num > 0); } return (tmp); } int main(void) { int nx = scan_uint(); printf("反転した値は%dです。\n", rev_int(nx)); return 0; } 教えてください!参考書に書いてあることをまとめて プログラムを読んでるのですが、わからない部分があります。 (1)まずint scan_uint(void)からこのプログラムは読み込んでるのでしょうか? どこかのサイトを調べたら、最初にint mainからプログラムは 読み込むというのを観たのですが、コンパイルして実行した動きをみるかぎり一番最初はint scan_uint(void)から読んでるように見えます。。。 (2)int scan_uint(void)の文は理解できました。私なりに解釈したのは ここでは正の数を入力しないと次に進まないことと 負の数を入力した場合、負の数を入力しないでくださいと注意がずっと でるという文です。 質問ですが、このあとint rev_int(int num)文に移ると思うのですが ここの int tmp = 0; これはこのint rev_int(int num)文のみの tmpの箱と参考書に記載がありました。つまり int scan_uint(void)で 出てきたtmpとは別個と解釈しました。 そうなると、int rev_int(int num)文を読んでみると tmpの箱を作成。そこは0を代入。 if文で num>0の時、 do文に入る (ここでいうnumは int numと宣言してないですけど、またscanfとか作って値はまだいれてないですけど??) do文は tmp = tmp*10 + num %10 num /=10 wile(num>0) これを見る限り、numという箱が見えません。全体を見渡しても どこかでnumに値が代入されたのち、このint rev_int(int num) という文を読みこんでいき if num>0のときと宣言されていますが もっと前の段階でnumの値が入力されていない限り このif文は適用されないと思ったのですが、プログラムは動いてます 三つ目の質問です tmp = tmp *10 + num % 10 num /=10 の部分がわかりませんでした。 tmpはまず、int scan_uint(void)で作成したtmpと int rev_intで登場してきたtmpとは別個と参考書に書いてあるのが 正しいのであれば tmpの値はここでは初のはずです。 一体いつ値を入力したのでしょうか? もしも一番最初のscanfの時に入力した例えば12345が此処でも適用されるなら tmp = 12345 ×10 + num % 10を tmpに代入するって文になりますが どうしてtmpを10かけるのですか?123450になり、 そのあとnumの値が此処でもまだ不明なのですがnum/10したものと 足すみたいですが、わかりませんでした。。。 まとめると、tmp = tmp*10+num%10がわかりません。 また、numとは何かわかりません、値もどの値がどこで代入されていて while(num>0)が引っかかるのか不明です。 tmpはint scan_uint文内で入力した値(scanfの部分で) 12345と仮に入力したら、それは次のint rev_int(int num)でも続いて活用されてるのですか? 参考書はなぜ別個と書いてるのかわかりません。 ごめんなさい>_< とても長くなりました。 どなたか解る方、教えてください、よろしくおねがいします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.2

(1) C言語の場合「書いてある順番」と「実行する順番」は、まったく関連がありません。 決まっているのは「必ずmain関数から実行する」と言う事だけです。 因みに「実行を開始する場所(ポイント)」のことを「エントリポイント」と呼び、Cでは「main関数の先頭がエントリポイント」と決まっています。 (2) >質問ですが、このあとint rev_int(int num)文に移ると思うのですが いいえ。移りません。 これが「そもそもの誤解の始まり」です。 上記(1)で言った通り、必ずmainからプログラムが動き始めます。 main関数で int nx = scan_uint(); printf("反転した値は%dです。\n", rev_int(nx)); と、それぞれの関数を呼んでいるので、実際の動作を実行順に羅列すると 1.必ずmainの先頭からプログラム開始。 2.mainからscan_uintが呼ばれる。 3.呼ばれたscan_uintが処理を行う(内容は理解しているようなので省略) 4.scan_uintからmainに帰ってくる。その時の戻り値がnxに入る。 5.printfの引数にrev_int(nx)があるので、nxを引数にしてrev_intを呼ぶ。 6.呼ばれたrev_intは、nxの値をnumとして受け取る。 7.rev_intは受け取ったnum(mainのnxと同じ値)を元に処理を行う。 8.rev_intはtmpに作った値を戻り値として関数を終わる。 9.rev_intからmainに帰ってくる。その時の戻り値がprintfの引数になる。 10.mainからprintfが呼ばれる。 11.呼ばれたprintfは何かを画面に表示し、関数を終わる。 12.printfからmainに帰ってくる。printfの戻り値は受け取ってないので捨てられる。 13.mainがreturn 0;で関数を終わらせ、プログラムが終了する。 となります。 >これを見る限り、numという箱が見えません。全体を見渡しても 上記の6.で「引数の実体として、mainから渡してもらってる」でしょう? それが判らなかったのは「プログラムはmainの先頭から実行する」と言うのを理解できていないからです。 (3) >tmp = tmp *10 + num % 10 >num /=10 の部分がわかりませんでした。 >どうしてtmpを10かけるのですか?123450になり、 123450にはなりません。 rev_intに入ってきたら int tmp = 0; ってやってるので、tmpは「最初は0」です。別の場所(scan_uintなど)にあるtmpは「同姓同名の赤の他人」なので忘れましょう。 scan_uintで「12345」を入力すると、12345がmainのnxに返って来て(nxが12345になって)、そのnxの値である12345がrev_intに渡され、rev_intは12345をnumに受け取ります。 つまり「最初は、numは12345、tmpは0になっている」のです。 そして、numが0かどうか調べます。 numが0でない(12345になっている)ので、次に tmp = tmp *10 + num % 10; を実行します。 tmp(中身が0)を10倍した値と、numを10で割った余りを足し、tmpに戻しています。 つまり0を10倍した0に、12345を10で割った余り5を足し、足した結果5をtmpに戻します。なのでtmpは5になります。 次に num /=10; を実行します。 これは「numを10で割って、numに戻す」です。 num = num / 10; と同じです。 numは12345なので、10で割った商1234がnumの新しい値になります。 なお、Cでは、整数の割り算の答えは「商」だけです。小数点以下はありません。例えば、1を10で割ると0になります。 次は、while文で「numが0より大きいなら繰り返し」です。 numが0より大きい(1234になっている)ので繰り返すことになり、また tmp = tmp *10 + num % 10; を実行します。 tmpは5になっているので10倍して50、それにnum(1234)を10で割った余り4を足し、足した54をtmpに戻します。 次に num /=10; を実行します。 numは1234なので、10で割った商123がnumの新しい値になります。 これを「numが0より大きい間、繰り返し」すると tmp=0、num=12345 ↓ tmp=5、num=1234 ↓ tmp=54、num=123 ↓ tmp=543、num=12 ↓ tmp=5432、num=1 ↓ tmp=54321、num=0 となり、numが0になって繰り返すのをやめた時、tmpは54321になっています。 そして、最後に return tmp; として、54321をmainに返します。 mainに帰って来ると、前述の9.~11.の処理で 反転した値は54321です。 と表示されます。 >参考書はなぜ別個と書いてるのかわかりません。 「別の場所にある、同じ名前の変数は、同姓同名の赤の他人」なので「別個」です。

nana070707
質問者

お礼

すごく、丁寧に教えていただいて>_< こんなにたくさん説明を書いていただいて、すごく解りやすかったです!!  本当にありがとうございます!! <(_ _)> <(_ _)> <(_ _)> もっとC言語の勉強頑張ります!! ありがとうございました!!!!!!!!!!!

その他の回答 (1)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

(1)main関数を最初に実行します。今回は、main関数の先頭部分でscan_uint関数を実行していますので、 あたかもscan_uint関数を最初に実行しているように見えているだけです。 (2)rev_int関数のnumを定義していない、とのことですが、関数の先頭部分 int rev_int(int num) で、rev_int関数のint型の引数として定義済みです。 (3)rev_int関数のtmpは、同関数の先頭部分で int tmp = 0; このように、定義と初期化を行なっています。scan_uint関数のtmpとは、全く別物です。

nana070707
質問者

お礼

返事、書いていただいてありがとうございました! とても参考になりました!!!! 本当にありがとうございました!!!

関連するQ&A

  • while文の作成について

    キーボードに整数を打ち込み、0を打ち込むと終了し、その合計を出すプログラムを以下のように作りました。 #include<stadio.h> int main(void){ int num=0 int sum=0 printf("整数を入力"\n"); do{ scanf("%d",&num); sum +=num; }while(num); printf("合計は%dです。\n",sum); returen 0; } 次に負の値が入力されるまで整数を読み込み続け、その合計をを求めるプログラムを作りたいのですが、whileのところを }while(num>=0); としてみたのですが、うまくいきません。また分かり易くするため、入力した整数の個数も表示できるようにしたいです。どうすればよいでしょうか。詳しい方、教えてください。

  • for文

    整数を読み込んで、その値を0までカウントダウンしながら表示するプログラム作りたいのですが、 while文ではできたのですが、for文ではうまくいきません。 どこが間違っているのでしょうか? OS:Windows XP C++Builder X パーソナル #include <stdio.h> int main(void) { int i; int num; printf("整数を入力してください:"); scanf("%d", &num); for(i = num; i <= 0; --i) { printf("%d", i); } return 0; } 宜しくお願いします。

  • for文

    #include <stdio.h> int main(void) { int i; int sum=0; int num, tmp; printf("整数は何個かな:"); scanf("%d",&num); for(i=0; i<num; i++){ printf("No.%d:",i+1); scanf("%d",&tmp); sum+=tmp; } printf("合計値は:%d\n",sum); printf("平均値は:%.2f\n", (double)sum/num); return(0); } 上の文のforの箇所を for(i=1; i<=num; i++){ printf("No.%d:",i); scanf("%d",&tmp); sum+=tmp;   } としても結果的に同じですよね? どっちでもいいかどうか迷ってます。教えて下さい。

  • c言語 for文

    /*指定された個数だけ整数を読み込んで合計値・平均値を算出*/ #include <stdio.h> int main(void) { int i; int sum=0; int num,tmp; printf("整数は何個ですか:"); scanf("%d",&num); for(i=0;i<num;i++) {printf("No.%d:",++i); scanf("%d",&tmp); sum = sum + tmp; } printf("合計値:%d\n",sum); printf("平均値:%.2f\n",(double)sum / num); return(0); } C言語の勉強を始めたばかりのものです。 指定された個数だけ読み込めません 汗 前置と後置をまぜたあたりがよくないのかなと思うのですが。。。 どうしておかしくなるのか教えてください。 内部でどういった処理が行われているのかまだあまりわからない状態です。 ちなみに4と入力した結果は以下です。 整数は何個ですか:4 No.1:4 No.3:3 合計値:7 平均値:1.75

  • char型にint型の数値を代入する。

    たとえば、 int num; char box;  numに何らかの整数値が入っているときに、そのnumの中に入っている値をchar型に文字列として代入したいときはどのようにすればいいのでしょうか?

  • while文を使った問題なのですが・・

    はじめまして。 C言語初心者です。 while文のところまでやっとたどり着きましたが、次の問題がどうしても解くことができません。 ********************** 整数を入力し、入力された整数の数だけ「*」を横一列に表示し、最後に改行するプログラムを while 文を使って作りなさい。 但し、0または負の値が入力された場合は、「*」は表示せず、改行のみを表示すること。 ********************** #include<stdio.h> int main(void) { int a; scanf("%d", &a); while(a!==0){ printf("%d*\n", a); } } こんな感じでつくってみたのですが、whileの条件部分がさっぱり分かりません。 int a の数字文だけ、*で表示する、というのも方法が思いつきません。 アドバイス、お願いいたします。

  • int num[10]という配列に、適当な整数が入っています。

    int num[10]という配列に、適当な整数が入っています。 この中から、数字が大きいものを上から3つ取り出して出力するプログラムを書きたいのですが、どうしたら良いでしょうか? 簡単なIF文で最大や最小を取り出すことは出来るのですが、上から3つというのが分かりません。 以前作ったバブルソートのプログラムを使って取り出せたのですが、もう少し簡単にできるような気がするのです。 ヒントなど、教えて頂けませんか?

  • C言語初心者です。次の問題で質問です。

    (問題) 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値表示するプログラムを作成せよ。 (自分の解答) #include <stdio.h> int main(void) { int num1,num2; int sum=0; do { printf("整数1>整数2となる整数をそれぞれ入力してください\n"); printf("整数1:"); scanf("%d",&num1); printf("整数2:"); scanf("%d",&num2); if (num1 < num2) printf("整数1>整数2としてください\n"); } while (num1 < num2); printf("%d以上%d以下の全整数の和は",num2,num1); for (num2;num2 <= num1;num2++) { sum=sum+num2; } printf("%dです。",sum); return 0; } これでも一応正しく実行されるのですが、ごちゃごちゃしてるので簡潔に書けないでしょうか? 回答お願いします。

  • C言語のプログラミング (基礎)配列の問題ですが。

    次のような問題があって、プログラミングしてみたのですが、 コンパイルすると永久ループになってしまいます。 また、入力されるはずの整数が表示されません。 どうすればよいか教えていただけると助かります。 よろしくお願いします。 整数を順番に入力し、負の数が入力されたら、それまでに入力された非負の整数を、 入力された順番とは逆に全角空白で区切って出力するプログラムを作成しなさい。 自動評価の都合上、上記以外は表示しないこと。なお、入力は最大10回とする。 【0 1 2 3 4 -1 が入力された場合の表示例】 4 3 2 1 0       ************************************** #include <stdio.h> int main(void) { int num[10]; int n; for(n=1;n<11;n++){ printf("整数入力:¥n"); scanf ("%d", &num[n]); if(num[n]<0){ for(n=10;n>0;n--){ printf("%d ",num[n]); } } } }

  • Cのポインタについて(関数への値渡し)

    C言語のポインタに関する質問です。関数に引数を渡す方法として以下の誤ったswap関数でなぜだめなのかいまいち得心できません。わかりやすくかみくだいて説明していただけると有り難いです。 できましたら、トレースともうしますか、変数の値の動きを詳細に段階的にプログラムの流れに沿って追っていって、だからこうなんだよ、みたいな解説がいただけたら有り難いです。わがままいってすみません。 /* 誤ったswap関数の宣言 */ void swap(int x, int y); int main(void) { int num1 = 5; int num2 = 10; printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); printf("変数num1とnum2の値を交換します。¥n", num1); swap(num1, num2); printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); return 0; } /* 誤ったswap関数の定義 */ void swap(int x, int y) { int tmp; tmp = x; x = y; y = tmp; } ---------- /* swap関数の宣言 */ void swap(int *pX, int *pY); int main(void) { int num1 = 5; int num2 = 10; printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); printf("変数num1とnum2の値を交換します。¥n", num1); swap(&num1, &num2); printf("変数num1の値は%dです。¥n", num1); printf("変数num2の値は%dです。¥n", num2); return 0; } /* swap関数の定義 */ void swap(int *pX, int *pY) { int tmp; tmp = *pX; *pX = *pY; *pY = tmp; }

専門家に質問してみよう