自作関数を作ると・・・
#include <stdio.h>int myprint(int num)
{
printf( "%d\n", num );
printf( "%d\n", num * 2 );
printf( "%d\n", num / 2 );
return num * 2;
}
int main(void)
{
int num;
printf( "整数を入力して下さい\n" );
scanf( "%d", &num );
num = myprint( num );
myprint( num );
return 0;
}
1つの数値を入力すると、
50
100
25
100
200
50
のように、同じことを2回繰り返しますが、mainにmyprint( num ); とあるからですか? どうして繰り返すのか分かりません。
回答(1)
2.
mainにmyprint( num ); とあるからです。
関数myprint()の仕様は、
引数numを
「そのままの値」
「2倍の値」
「半分の値」
とそれぞれ表示し、
引数numの「2倍の値」を戻り値にしています。
今回のケースでは、
この処理を2回繰り返しているわけですから、
この関数が2回呼び出されている可能性がありますよね。
そこでmain()を見てみますと、
num = myprint( num );
myprint( num );
と2回呼び出されています。
この処理を順番に見ていきますと、
(main関数)
入力されたnumをmyprint関数に渡す
↓
(myprint関数)
numを指定の形で表示し、numの2倍の値を戻す
↓
(main関数)
戻された2倍の値をnumに代入
その2倍の値になったnumをmyprint関数に渡す
↓
(myprint関数)
numを指定の形で表示し、numの2倍の値を戻す
となっています。
コメント(7)
感覚が難しいですね。 なぜ、mainにはreturn文がないのにmainにあるものを他の関数に渡すことができるですか?
同じ名前の関数を作ると、リンクされるのですか。
>#1
なぜ、mainにはreturn文がないのにmainにあるものを他の関数に渡すことができるですか?
ごめんなさい。ご質問がよく理解できませんでした。
ですのでトンチンカンな回答になるかもしれません。
C言語はmain関数の先頭から処理が始まり、
main関数の最後の行で処理が終わります。
また、(呼び出される側の)関数は、
「コピーされた値を受け取り、戻り値を戻す」
という設計を前提に関数を書きます。
そして、関数を呼び出すときは、
「値をコピーして渡し、戻り値を受け取る」
という仕様で呼び出します。
これは「考えるもの」ではなく「覚えるもの」
と割り切ったほうがいいと思います。
同じ名前の関数を記述したときエラーが出ないかどうかは、
C++にはオーバーロードという仕様がありますので
CとC++(C#)で違ってきます。
改めてどちらかを明示された上で
別の質問として書かれてみてはいかがでしょうか。
補足)
ポインタについて書いていませんでした;;
また、(呼び出される側の)関数は、
「コピーされた値を受け取り、戻り値を戻す」
→(ポインタの場合はポインタを受け取る)
という設計を前提に関数を書きます。
そして、関数を呼び出すときは、
「値をコピーして渡し、戻り値を受け取る」
→(ポインタの場合はポインタを渡す)
という仕様で呼び出します。
何度も書き直していて、
不完全なコメントのまま投稿して申し訳ありません。
ポインタ同士での呼び出し、受け取り、戻ししかないということですか? 質問のプログラムはポインタを含んでいないので、その例となるようなプログラムを見せていただけたらうれしいです。 お願いしていいですか。
>>#1 なぜ、mainにはreturn文がないのにmainにあるものを他の関数に渡すことができるですか?
main から呼び出しているからmain にあるものを使える。
メイン(呼び出し側)で
function(arg)のように関数を呼び出した場合
arg は、呼び出し側の変数なのでそのまま(呼び出し側で)使えます。
function 側では、渡された(指定された)変数のコピーを(大抵はスタックに)作りそれを利用します。
関数(引数,…)
という関数の呼び出しは
呼び出し側の変数を関数側に渡して関数を呼び出すということを意味します。
BLUEPIXYさんの書かれているとおり、
呼び出し側で値を渡す場合も、アドレスを渡す場合も、
呼び出される側の関数に渡される値は、それぞれ
コピーされた値、コピーされたアドレス
が渡されます。
ただ、アドレスを渡す場合、
コピーされたアドレスの指し示す内容は不変ですから、
結果として、そのアドレスに直接アクセスして
内容を書き換えることができます。
例えば、main関数で2000番地に1を書き込んだとします。
そしてmyprint関数に2000番地というアドレスを渡した場合、
2000番地という数字はコピーされますが、
2000番地に書かれている1という数字はそのままです。
そして、その値は直接読み書きできますから、
関数を抜けるとき、
その内容をreturn文で戻す必要はありません。
ご質問のコードで無理矢理ポインタを使ってみます。
(でも、こんなコードを書いていると怒られそうですよね。
あくまで例ということで……)
#include <stdio.h>
int myprint( int *num ) //ポインタを受け取る
{
printf( "入力値は %d\n", *num ); printf( "その2倍は %d\n", *num * 2 ); printf( "その半分は %d\n", *num / 2 ); *num = *num * 2; //数字を倍にして書き込む}
int main( void )
{
int num; printf( "偶数を入力して下さい\n" ); scanf( "%d", &num ); myprint( &num ); //ポインタを渡す printf( "現在の値は %d\n", num ); return 0;}



