main関数内で定義された配列に格納されている数値データを自作関数を使って変更してみましょう。自作関数の引数が(int* hairetu)となっている場合🌞

アレサ


「ここで再び配列の仕組みにもどってみますの。


#include <stdio.h>


int main (void){


int hairetu[]={1,2,3,4,5};


int i;


for(i=0;i<5;i++)


printf("%d\n",hairetu[i]);


return 0;


}


コンパイル結果


1

2

3

4

5



アレサ「ここでは配列hairetuの配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


1

2

3

4

5


の5つの数値データをとりこみ


for(i=0;i<5;i++)


printf("%d\n",hairetu[i]);


の命令文により


コンパイル結果

1

2

3

4

5


を表示しています。」



ソーラー「配列宣言


int hairetu[]={1,2,3,4,5};



おこない


生成された


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


に数値データ1,2,3,4,5を


hairetu[0]=1;

hairetu[1]=2;

hairetu[2]=3;

hairetu[3]=4;

hairetu[4]=5;


のように取り込んでいると


そういうわけなんだねっ くすっ」




アレサ「この配列宣言int hairetu[]


を自作関数の引数の部分に記入し


main関数内で定義された別の配列のアドレス情報を


自作関数の引数に参照渡しすることができましたね。」


ソーラー「そうだったね😊」


アレサ「


配列を引数とした自作関数を使って構成された


プログラムは次のようなものでした。」



#include <stdio.h>


void newmadefunction(int hairetu[]){


*hairetu=*hairetu*2;

*(hairetu+1)=*(hairetu+1)*2;

*(hairetu+2)=*(hairetu+2)*2;

*(hairetu+3)=*(hairetu+3)*2;

*(hairetu+4)=*(hairetu+4)*2;


}


/*int hairetu[]を自作関数newmadefunction(int hairetu[])の()内にかきこみました*/


int main (void){


int newhairetu[5]={1,2,3,4,5};


newmadefunction(newhairetu);



/*配列newhairetuのアドレスを格納している


ポインタ変数newhairetuが自作関数の引数として


int hairetu[]に代入されています*/



int j;


for(j=0;j<5;j++)


printf("%d\n",newhairetu[j]);


return 0;


}


コンパイル結果


2

4

6

8

10



アレサ「

このプログラムでは


冒頭の自作関数宣言で自作関数newmadefunctionの引数を


配列とするためにnewmadefunction()の()内で


配列宣言int hairetu[]をおこなっています


そしてmain関数内で


新しくつくられた配列newhairetu


のアドレスを格納しているポインタ変数newhairetu


を自作関数


newmadefunction(int hairetu[])内の引数である


int hairetu[]に代入しています・・・・・・



ここで


int hairetu[]を int* hairetuと記述して


プログラムを次のように書き換えることができます



#include <stdio.h>


void newmadefunction(int* hairetu){


*hairetu=*hairetu*2;

*(hairetu+1)=*(hairetu+1)*2;

*(hairetu+2)=*(hairetu+2)*2;

*(hairetu+3)=*(hairetu+3)*2;

*(hairetu+4)=*(hairetu+4)*2;


}


/*int* hairetuを自作関数の()内に引数としてかきこみました*/


int main (void){


int newhairetu[5]={1,2,3,4,5};


newmadefunction(newhairetu);



/*配列newhairetuのアドレスを格納している


ポインタ変数newhairetuが自作関数の引数として


ポインタ変数hairetuに代入されています。


*/



int j;


for(j=0;j<5;j++)


printf("%d\n",newhairetu[j]);


return 0;


}


コンパイル結果

EAZY IDECの場合

2

4

6

8

10


Visual Studioの場合

2

4

6

8

10


アレサ「ここで注目するべきところは


やはり


自作関数newmadefunction(int* hairetu)の


引数 int* hairetuに


配列newhairetuのアドレスを格納している


ポインタ変数newhairetuを


代入しているところです。」



ソーラー「



main関数内で定義された配列newhairetuのアドレスを格納している


ポインタ変数newhairetuを


自作関数の引数である


int* hairetuに


代入する???


😊😊😊

オオウ ノウ

オオ~~~~~ ノウ~~~~~~~

オオオオオオオオ ノウ~~~~~~

オオウ オオウ ノウ

オオ~~~~~ホワット? ノォノウ~~~

オオオオオオオオオオオオオオオオ ノウ~~~~~~

ノン

オオ~~~~~ ノウ~~~~~~~

オオオオオオオオ ノウ~~~~~~

オケェ~

オ~イェエ~~


オオウ ノウ

ホワァイ~


オ~


セェイ イェエ~~

オオオオウ~~~~~ ノウ~~~~~~~

ノウ~~~~~~~~~~~~~~


わんわん

オオオオオオオオオオオオオオオオ 

わたしわかりません


どういうこと?????


前のエピソードでは


main関数内で定義された配列newhairetuのアドレスを格納している


ポインタ変数newhairetuを


自作関数の引数である


int hairetu[]に代入していたね。


ま 


それは何とか分かったんだけど・・・


main関数内で定義された配列newhairetuのアドレスを格納している


ポインタ変数newhairetuを


自作関数の引数である


int* hairetu


に代入する???????


ポインタ変数newhairetuを

ポインタ変数hairetuに代入するということだよね???


いやぁ


確かに


ポインタ変数newhairetuを

ポインタ変数hairetuに代入する


ことは可能なんだろうけど


main関数内で定義された配列newhairetuのアドレスを格納している


ポインタ変数newhairetuを


自作関数の引数である


int* hairetu


に代入することに


どのような意味があるのか?


というところが分からないよね。


わかるわけがないよね。」




アレサ「ここでなぜ


配列のアドレスを格納した


ポインタ変数newhairetuを自作関数の引数に代入するのに



  引数に  ポインタ変数宣言int* hairetuが行われているのか




不思議とおもわれますか。


じつは理由を聞いてしまえばとても簡単なことなんですの。」



ソーラー「え~そうなのかい?


とてもそうはみえないけど?」


アレサ「実は


[ ]演算子のエピソードでもみてきたように


自作関数の引数となっているポインタ変数宣言int* hairetuによって


生成されるポインタ変数hairetuに


🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞

配列newhairetuのアドレスを格納しているポインタ変数newhairetu

🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞🌞


             🌞🌞🌞🌞🌞🌞🌞🌞

   が       

             🌞🌞🌞🌞🌞🌞🌞🌞 


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

をつかって


メモリにアクセスすることができるようになるのです。


まず


ポインタ変数hairetuに


配列newhairetuのアドレスを格納している


ポインタ変数newhairetuが代入されると


どのようなことが起こるかについてですが


ここでは


main関数内で配列宣言されて作製された


配列newhairetu[5]の要素数5にあわせて


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


だけ取り出して考えてみます


ソーラー「


それはつまり


int* hairetu


配列宣言

int hairetu[5];

おこなっているということ?」


アレサ「正確には


配列宣言

int hairetu[5];


がおこなわれているわけではありませんが


配列hairetuが作製されて


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


が生成されていると思われても構いません。


そして


この配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


はポインタ変数でないので


配列newhairetuのアドレスを格納している


ポインタ変数newhairetuが


ポインタ変数hairetuに代入されても


newhairetu[0]のアドレスを格納しているポインタ変数newhairetu

newhairetu[1]のアドレスを格納しているポインタ変数newhairetu+1

newhairetu[2]のアドレスを格納しているポインタ変数newhairetu+2

newhairetu[3]のアドレスを格納しているポインタ変数newhairetu+3

newhairetu[4]のアドレスを格納しているポインタ変数newhairetu+4


を格納することはできません。


格納してもいみないのですの。」



ソーラー「そう、またまたそのとおり😊\(^o^)/


やっぱり 読者のみなさんもそう思うよね」




アレサ「ですが


自作関数の引数の()内で


ポインタ変数宣言


int* hairetuが行われ


ポインタ変数hairetuにポインタ変数newhairetuが代入されたとき


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


を用いて


メモリにアクセスすることができるようになるのですが


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

のアドレスを格納しているポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


も同時に生成されています


つまり


自作関数の引数である()内のint* hairetuによって生成される


ポインタ変数hairetu



配列newhairetuのアドレスを格納しているポインタ変数newhairetuを


代入するということは


自作関数newmadefunction(int* hairetu)の()内の


ポインタ変数宣言


int* hairetu


によって作られることになったポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4



newhairetuの配列宣言によって作られたポインタ変数


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


を代入していることになります。」


ソーラー「なういっ!


い、いや


なっなんだってぇ~」



アレサ



このようにして


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


のアドレスを


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


のアドレスを格納しているポインタ変数


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


を使って


配列hairetuのポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


に代入すると


自作関数の定義の


*hairetu=*hairetu*2;

*(hairetu+1)=*(hairetu+1)*2;

*(hairetu+2)=*(hairetu+2)*2;

*(hairetu+3)=*(hairetu+3)*2;

*(hairetu+4)=*(hairetu+4)*2;



*newhairetu=*newhairetu*2;

*(newhairetu+1)=*(newhairetu+1)*2;

*(newhairetu+2)=*(newhairetu+2)*2;

*(newhairetu+3)=*(newhairetu+3)*2;

*(newhairetu+4)=*(newhairetu+4)*2;



がおこなわれることに等しくなります


*newhairetu

*(newhairetu+1)

*(newhairetu+2)

*(newhairetu+3)

*(newhairetu+4)



それぞれ


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


に格納されている数値データをあらわすため


*newhairetu=*newhairetu*2;

*(newhairetu+1)=*(newhairetu+1)*2;

*(newhairetu+2)=*(newhairetu+2)*2;

*(newhairetu+3)=*(newhairetu+3)*2;

*(newhairetu+4)=*(newhairetu+4)*2;


の実行により

newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


に格納されている数値データは2倍になります。


このようにして


ポインタ変数宣言


int* hairetu


によって作製されるポインタ変数hairetuに


ポインタ変数newhairetuを渡す


つまり


配列hairetuのポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4

newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


のアドレスを参照渡し(ポインタ渡し)することにより


自作関数をつかって


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


に格納されている数値データを変更できるというわけです。」


ソーラー


「main関数内で作製された配列newhairetuの


配列変数


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


に格納されている数値データが


自作関数の操作をうけて変更される・・・


そうそう これは(^_^)v


まさに 参照渡し(ポインタ渡し)のときに起こるパターンだったね」


アレサ「今のプログラムでは


main関数内で


自作関数newmadefunction(int* hairetu)


の引数となっているポインタ変数hairetu



main関数内で定義された配列newhairetuのアドレスを


格納しているポインタ変数newhairetu


が代入された命令文


newmadefunction(newhairetu);


が記述されています


このように


配列newhairetuのアドレスを格納しているポインタ変数newhairetuを


自作関数の引数のint* hairetuによって作製された


ポインタ変数hairetuに代入することにより


自作関数を使って


配列newhairetuに格納されている数値データの値が


変更できるようになります。


この関係は


先の参照渡し(ポインタ渡し)のエピソードにおいて


自作関数newmadefunction(int* ptx)の


()内でポインタ変数宣言された


ポインタ変数ptxに


main関数内で定義された変数aのアドレス&aを代入する


参照渡し(ポインタ渡し)の関係といっしょですの。


このときも


ポインタ変数ptxに


main関数内で定義された変数aのアドレス&aを代入する


ことにより


*ptxを自作関数の定義にもちいた


自作関数を使って


main関数内で定義された変数aに格納されている


数値データの値を変更できるようになりました。


つまり int* hairetuにより作製されるポインタ変数hairetu


はポインタ変数ptxにあたり


newhairetuは変数aのアドレス&aにあたるというわけですの。」


ソーラー「


ポインタ変数newhairetuが代入された


ポインタ変数宣言


int* hairetu



hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


だけでなく

hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


もつくっているか・・・


そんな仕組みだったんだね


アレサ ありがとう」




アレサ「お役に立てて嬉しいですの」




ソーラー「だから


配列newhairetu


のアドレスを格納しているポインタ変数newhairetu


を自作関数の引数int* hairetuに代入するということは


つまり


hairetu=newhairetu;

(hairetu+1)=(newhairetu+1);

(hairetu+2)=(newhairetu+2);

(hairetu+3)=(newhairetu+3);

(hairetu+4)=(newhairetu+4);


を実行していることになるんだね。


その際


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


を代表して


配列newhairetuのアドレスを格納しているポインタ変数



          newhairetuを



配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


のアドレスを格納しているポインタ変数

hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


を代表している


int* hairetuによって作製されるポインタ変数


hairetu


に代入しているんだね。」




アレサ「はい、そうですの


そして


このプログラムにおいて


配列newhairetuの


アドレスを格納したポインタ変数newhairetuを


自作関数newmadefunctionの引数となっている


int* hairetuによって作製されたポインタ変数hairetuに


代入したように



一般に、



自作関数()内で(int* hairetu)のように


ポインタ変数宣言されたポインタ変数hairetuに


main関数内で定義された配列(例newhairetu[5])のアドレスを渡すには


main関数内で定義された配列(例newhairetu[5])のアドレスを


格納したポインタ変数


つまり


配列名(例newhairetu) を


自作関数()内で(int* hairetu)のように


ポインタ変数宣言されたポインタ変数hairetuに


代入するルールとなっています。


そうして


newmadefunction(newhairetu);


のように


自作関数の引数として


newmadefunction(int* hairetu)


のint* hairetuにより作製されるポインタ変数


hairetuに


main関数内で定義された配列newhairetuのアドレスを


格納しているポインタ変数newhairetuが代入されたなら


*hairetu

*(hairetu+1)

*(hairetu+2)

*(hairetu+3)

*(hairetu+4)



main関数内で定義された配列newhairetu


の配列変数

newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


のアクセスしているメモリにアクセスすることになり



main関数内で定義された配列newhairetuに格納されている数値は


自作関数の操作

*hairetu=*hairetu*2;

*(hairetu+1)=*(hairetu+1)*2;

*(hairetu+2)=*(hairetu+2)*2;

*(hairetu+3)=*(hairetu+3)*2;

*(hairetu+4)=*(hairetu+4)*2;


を受けて


変更できるようになります



このプログラムでは


main関数内での配列宣言


int newhairetu[5]={1,2,3,4,5};


により生成された


配列newhairetu内の配列変数


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]



newhairetu[0]=1

newhairetu[1]=2

newhairetu[2]=3

newhairetu[3]=4

newhairetu[4]=5


と格納されていた数値データが


自作関数の操作を受けて


newhairetu[0]=2

newhairetu[1]=4

newhairetu[2]=6

newhairetu[3]=8

newhairetu[4]=10


となっているのがわかります」


ソーラー「配列newhairetuに格納されている数値データが2倍されているね。


参照渡し(ポインタ渡し)を行うことにより


自作関数をつかって


main関数内で定義された配列newhairetuに


格納されている数値データを2倍に成功\(^o^)/💖したってわけだね」


アレサ


「ここで 


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


のアドレス


&newhairetu[0]

&newhairetu[1]

&newhairetu[2]

&newhairetu[3]

&newhairetu[4]


を格納しているポインタ変数は


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


となっています


このように


ポインタ変数newhairetuは


配列newhairetu内の


5つの配列変数


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]


の先頭の


newhairetu[0]のアドレス


&newhairetu[0]を格納していながら


かつ


配列newhairetuを代表する


ポインタ変数となっていますね


ポインタ変数newhairetuを


int* hairetuにより作製されるポインタ変数hairetuに渡せば


ポインタ変数

newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4



ポインタ変数

hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


hairetu=newhairetu;

(hairetu+1)=(newhairetu+1);

(hairetu+2)=(newhairetu+2);

(hairetu+3)=(newhairetu+3);

(hairetu+4)=(newhairetu+4);


このように


代入されるよう設定されているのですの」



ソーラー 「


自作関数newmadefunctionの実行時


配列newhairetuのアドレスを格納している


ポインタ変数


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


をnewhairetuで1括して


自作関数newmadefunctionの引数にわたすために


自作関数newmadefunctionの定義を


newmadefunction(int* hairetu)


と記述するシステムがC言語では用意されているんだね。


もうちょっと別の言い方をすると


自作関数newmadefunction(int* hairetu)の引数であるポインタ変数hairetu


に配列newhairetuのアドレスを格納している


ポインタ変数newhairetuが代入されるとき


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]



配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


のアドレスを格納しているポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4



ともに生成されています


そして


ポインタ変数hairetuは


配列変数

hairetu[0]のアドレスを格納しているポインタ変数であり


hairetu[0]のアドレスは


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]


を代表しているアドレスともいえるね。


hairetu[0]のアドレスは


配列hairetuのアドレスになっているともいえるかな


同様に


ポインタ変数newhairetuは


newhairetu[0]のアドレスを格納しているポインタ変数であり


newhairetu[0]のアドレスは


配列newhairetuのアドレスでもあるね。


だから

ポインタ変数宣言


int* hairetuに


よって生成されるポインタ変数


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


を格納するのに


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


を代表して


配列newhairetuのアドレスを格納しているポインタ変数


newhairetu



配列hairetuのアドレスを格納しているポインタ変数


hairetu


に代入されているといえるかな」





  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る