概ね方位不定だが多分割と偏っている
スポンサーサイト
--年--月--日 (--) | 編集 |
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


C 参照による呼び出し
2006年08月21日 (月) | 編集 |
前回やった、call by value(値による呼び出し)に対して、
call by referenceと呼ばれる手法だそうな。


関数はその構造上、戻り値を1つしか持てないそうなのだが、2つ以上の値を返したい場合もあるのだそうだ。そういう時は、関数の戻り値として2つの値を返すのではなく、ポインタを使って引数の受け渡しを行って、結果を引数を介して呼び出し元に返してやったりする。
これがcall by reference(参照による呼び出し)というやつだな。

func(&a,&b);
   ↓ aとbのメモリ上のアドレスを渡す
func(int *x,int *y)
{
 なんか式
}


上の例だと実引数aとbのアドレスを仮引数xとyに渡しているわけだ。
仮引数x,yはポインタ変数として宣言されているので、*xによって引数aの内容を参照することが出来る。
つまり、

*x=10

とするとポインタxに代入されているアドレスの参照先、つまり引数aの内容を10に変えることが出来る。後は、これを呼び出し元に返す、と。
こういう手法だな。
ポインタ変数ということで複数のデータを一方通行ではなくやり取り出来る便利な手段だが、それ故にサブルーチンの方でメインルーチンの引数の値を変化させてしまう危険性もあるので注意が必要らしい。

んじゃ例によって実際に組んでみようか。
aとbが与えられたとき、a+b、a-bを行う関数を作ってみる。

型 関数名(aの仮引数,bの仮引数,ポインタ変数1,ポインタ変数2)
{
 ポインタ変数1にa+bの結果を入力
 ポインタ変数2にa-bの結果を入力
}


データa,bは変化させてはいけない値なのでintで宣言し、
a+b、a-bの値を受け渡す為にポインタ変数をそれぞれ宣言する。

void add_sub(int a,int b,int *x,int *y)
{
 *x=a+b;
 *y=a-b;
}


こんな感じ。ここまではまあ楽やね。
この関数自体が数値を返すことはないのでvoid型になる。多分。
次にメイン関数部分。

入力される数値a,bとa-b,a+bの結果を入力する変数c,dを宣言
aに値を入力
bに値を入力

void main(void)
{
 int a,b,c,d;
 printf("値を入力したまえよ\n");
 scanf("%d",&a);
 printf("もう1個値を入力したまえよ\n");
 scanf("%d",&b);


a-b、a+bを求める関数add_subを呼び出す

 add_sub(a,b,&c,&d);

変えてはいけない値aとbはそのまま受け渡し、a+bとa-bをポインタ変数に渡す
後はデータを出力すればOK

 printf("足せば%d、引けば%dだぜ\n",c,d);
}


c_b_r_test.jpgc_b_r_test2.jpg
こんな感じ

これだけじゃまだよく分からんので、別の関数も作ってみよう。
aとb、どちらが大きく、どちらが小さいか比較する関数を作ってみる。

void max_min(int a,int b,int *max,int *min)
{
 if(a>b){
  *max=a;
  *min=b;
 }

 else{
  *max=b;
  *min=a;
 }
}


これについては特に問題ないだろう。
aとbを比較し、aが大きければmaxにa、minにbを、
そうでなければ(b>aなら)maxにb、minにaを代入しているだけだな。
後はメインプログラムで呼び出せばOK。

void main(void)
{
 int a,b,c,d;
 printf("値を入力したまえよ\n");
 scanf("%d",&a);
 printf("もう1個値を入力したまえよ\n");
 scanf("%d",&b);

 max_min(a,b,&c,&d);

 printf("大きい方は%d、小さい方は%dだぜ\n",c,d);
}


c_b_r_test3.jpgc_b_r_test4.jpg
こんな感じ

同じ値については何も指定してないのでどうにもならんな。


まとめよう。

2つ以上の値を受け渡したいときはポインタが便利なんだ
でもメイン関数で使うような値をうっかり変えてしまう可能性もあるので要注意だ


以上。
ちょっと難しくなってきたな。

スポンサーサイト

コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。