moushinisou

C言語初心者学習記Part5

ポインタ変数との格闘

御多分に漏れず、私もポインタ変数に苦労しましたw

ポインタ変数の宣言や機能はわかっていても関数が絡むと脳内がショートしてしまいます。

 

そこで、今回から数回、ポインタ変数で私が躓いた点を再考していきます。

先ず、今回はポインタ変数と関数についてです。

先ずは成果から

ポインタ変数との格闘の末出来上がったのが以下に紹介するプログラムです。

その名も「割り勘求める君」w

イマイチ使いどころがわからない謎のプログラムです。

今回は、一つの関数で複数の返り値を出すために、ただ割り勘した時の一人あたりの価格を出すだけでなく、「どれぐらい得をしたのか」や「いくら余るのか」もわかる様にしました。

守銭奴に嬉しい機能ですねw

因みに、これらの「一人あたりの価格」「どれくらい得をしたのか」「いくら余るのか」は同じ関数内で求めるようにしました。

↓とりあえずコードはコチラ↓


 

#include <stdio.h>

void hanbetu(int money,int person,int*a,int*b,int*c);
int *a,*b,*c;
/*この*a*b*cにper,balance,leftを渡します*/

int main(void)
{
int money,person;
int per,balance,left;

a=NULL;
b=NULL;
c=NULL;
/*前もってヌルポインターで初期化します*/

/*タイトル*/
printf(“\t================\n\t|割り勘求める君|\n\t================\n”);

/*入力部分*/
printf(“合計金額を入れてネ:”);
scanf(“%d”,&money);
printf(“\n割る人数を入れてネ:”);
scanf(“%d”,&person);
printf(“\n”);

/*処理部分*/

hanbetu(money,person,&per,&balance,&left);

/*出力部分*/
printf(“一人当たり%d円です。\n”,per);
printf(“貴方は%d円得しました。\n”,balance);
if(left==0){
printf(“綺麗に割り勘できました。”);
}else{
printf(“しかし、残念なことに%d円余ってしまいました。\n喧嘩でもして決着をつけてください。”,left);
}
printf(“\n\n”);
return 0;
}

void hanbetu(int money,int person,int*a,int*b,int*c)
{
*a=money/person;
*b=money-*a;
*c=money%person;
return;
}


 

因みに、実行画面はこんな感じです。

↓タイトル

c-5-0

 

↓入力画面

c-5-1

 

↓結果画面

c-5-2

2つ以上の返り値を返す関数を作る

基本的に一つの関数に付き返り値は一つです。

そのため、一つの関数内で複数の返り値が欲しい時に困ってしまいます。

そこで、ポインタ変数を使って同じアドレスを参照させることで値をメモリごと紐づけてしまうんですね。(いわゆる参照渡し)

そのため今回のプログラムでは、出力用のper,balance,left(いずれも通常変数)の他に*a,*b,*c(こっちはポインタ変数)を用意しています。

渡す先のhanbetu関数は戻り値を必要としないのでvoid型にしておきます。

hanbetu関数には&per,&balance,&leftを実引数にして渡すことでper,balance,leftのアドレスにアクセスさせます。

これらはhanbetu関数内でそれぞれ算出、*a,*b,*cのアドレスと紐づきます。

そのため、per,balance,leftの値をprintfで呼び出すと計算された値で表示されます。

 

…と書いたのですが、先ず*や&でアドレスをいじる行為が結構混乱しました。

「今何してるんだ?」

みたいな感じですw

 

私はここを復習した

おそらく、ポインタの挙動の理解が今一つだとここで詰まる気がします。

さらに、関数のおさらいをしておく必要がある気がします。

私も混乱して、自分で作った関数が何を意味しているのか分からなくなりました。

私がこのプログラムのhanbetu関数を作るにあたって見直した点を列挙しておきます…

 

1.int *aと宣言した場合、aと打てばポインタ変数、*aと打てば変数として動く

宣言した時の*とそれ以外での*は意味が違うという事ですね。

少なくとも私は慣れるまで時間がかかりました…

 

2.通常の変数のアドレスにアクセスしたいときは&をつける。

scanf関数で使いますね、今回はper,balance,leftに*a,*b,*cの算出結果を読み込ませるのに応用しています。

 

3.戻り値が必要ない関数の型はvoid型

関数は

型名 関数名(引数){処理内容}

となっています。

今回のvoid hanbetu(int money,int person,int*a,int*b,int*c){}

であれば、

hanbetuという関数はint型の変数money、int型の変数person、int型のポインタ変数*a、int型のポインタ変数*b、int型のポインタ変数*cを引数に{}内の処理を行い。void型の返り値を出しますよ(voidなので正確には無い。)

という事ですね。

実際に渡す引数はmoney,personはscanfによってキーボードから打ち込まれた値ですね。*a,*b,*cは&per,&balance,&leftでした。

 

 

しかし、ポイント変数にはもう一つの問題がありました。

長くなったのでそれは次回で…
【前→C言語初心者学習記Part4

【次→C言語初心者学習記Part6

0

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA