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

アレサ

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


#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に1,2,3,4,5の5つの数値データをとりこみ


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

printf("%d\n",hairetu[i]);の命令文により


1

2

3

4

5

をprintf出力表示しています。



ソーラー「hairetuの配列宣言、初期化


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関数内で定義された別の配列のアドレスを


この自作関数の引数となった


配列宣言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);


/*main関数内で配列宣言された配列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[]に代入しています・・・・・・



ここで注目するべきところは


やはり


自作関数newmadefunction(int hairetu[])の


引数 int hairetu[]に


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


ポインタ変数newhairetuを


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


ソーラー「


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


ポインタ変数newhairetuを


自作関数の引数である


int hairetu[]に


代入する???


どういうこと?

さすがに無理ぃぃぃぃぃぃ~~~


もう意味不明すぎてツッコミできません


配列にポインタ変数を代入する?


それはできないんじゃないかな?」


アレサ「ここでなぜ


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



    配列宣言int hairetu[]が行われているのか




   🐣なぜ そのようにC言語の作者は設定したのか 🐣





を考察していきます


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


ポインタ変数newhairetuがint hairetu[]に代入されるとき


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


🐤自作関数の引数であるint hairetu[]の要素数が5となり🐤


hairetuの配列宣言


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[0]のアドレスを格納しているポインタ変数newhairetu

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

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

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

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


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


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



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


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


アレサ「ですが


int hairetu[]が行われ


配列hairetu内に


配列変数


hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

が生成されると


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


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4

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


つまり


自作関数の引数である()内のint 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)


を代入していることになると思われます。」


☆  ☆  ☆

次のような考え方もあります


int hairetu[]にnewhairetuが代入されると


hairetu=newhairetu;


が実行されます


すると


hairetuとnewhairetuは同じアドレスを格納することになります


ですので


hairetu

hairetu+1

hairetu+2

hairetu+3

hairetu+4



newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4



等しいものを表すことになります



☆  ☆  ☆





ソーラー「なんだってぇ~」


アレサ「


ですから


C言語の作者さんが


       自作関数の()内はint hairetu[]でいいや


と設定したのも自然なことだったかもしれないですの」






ソーラー「アレサ、もうなんか🌞 冴えっ、冴え🌞」



アレサ、もうなんか 冴えっ、冴え

ぶっとんでます

かんがえつくかな ふつう こんなこと?


                 solarplexussより


アレサ

「このようにして


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=newhairetu;

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

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

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

(hairetu+4)=(newhairetu+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[]にポインタ変数newhairetuを渡す


すなわち


newhairetu[0]

newhairetu[1]

newhairetu[2]

newhairetu[3]

newhairetu[4]

のアドレスを参照渡しすることにより


自作関数をつかって


main関数内で配列宣言された配列newhairetuの


配列変数


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[]);



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


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


を代入する命令文


newmadefunction(newhairetu);


が記述されています


このように


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


自作関数の引数のint hairetu[]に代入することにより


              自作関数を使って


               main関数内で


定義された配列newhairetuに格納されている数値データを


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



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


自作関数newmadefunction(int* ptx)の


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


ポインタ変数ptxに


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


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


このときも


ポインタ変数ptxに


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


ことにより


*ptxを使って


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


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


つまり int hairetu[]はポインタ変数ptxで


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


ソーラー「

配列宣言


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

hairetu+1

hairetu+2

hairetu+3

hairetu+4

を代表している


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


に代入しているといえるかもしれないね。」


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


そして

このプログラムにおいて


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


配列newhairetu[5]の


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


自作関数newmadefunctionの引数(int hairetu[])に代入したように


一般に、


自作関数()内で配列宣言された配列(例int hairetu[])に


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


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


格納したポインタ変数


つまり


配列名(例newhairetu) を


自作関数()内で配列宣言された配列(例int hairetu[])に


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



そうして


newmadefunction(newhairetu);



自作関数の引数として(int hairetu[])に


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


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


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


自作関数の操作を受けて


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


このプログラムでは


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


により生成された


配列newhairetu内の配列変数に


newhairetu[0]=1

newhairetu[1]=2

newhairetu[2]=3

newhairetu[3]=4

newhairetu[4]=5


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


自作関数の操作


*hairetu = *hairetu * 2;

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

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

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

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


を受けて


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[]に渡せば


ポインタ変数

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);



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



ソーラー 「配列newhairetuのアドレスを格納している


ポインタ変数


newhairetu

newhairetu+1

newhairetu+2

newhairetu+3

newhairetu+4


をnewhairetuで1括して


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


自作関数(int hairetu[])


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


別の言い方をすると


配列宣言

int hairetu[]によって


配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

(int hairetu[]には配列newhairetu[5]を代表しているアドレスを格納しているポインタ変数newhairetuが代入されます

そして

生成されるhairetuの配列変数の数は


配列newhairetu[5]の要素数5により決定されます)



配列変数

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を代表するアドレスでもあるね。


同様に


ポインタ変数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で共有
  • はてなブックマークでブックマーク

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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