🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
main関数内で定義された配列に格納されている数値データを自作関数を使って変更してみましょう。自作関数の引数が(int hairetu[])となっている場合 その1
main関数内で定義された配列に格納されている数値データを自作関数を使って変更してみましょう。自作関数の引数が(int hairetu[])となっている場合 その1
てんC
「ここで配列の仕組みにもどってみます。」
#include <iostream>
using namespace std;
int main (){
int hairetu[]={1,2,3,4,5};
int i;
for(i=0;i<5;i++)
cout<<hairetu[i]<<"\n";
return 0;
}
ビルド実行結果
1
2
3
4
5
てんC「
このプログラムでは配列hairetuの配列変数に
1,2,3,4,5の5つの数値データをとりこみ
for(i=0;i<5;i++)
cout<<hairetu[i]<<"\n";の命令文により
1
2
3
4
5
をcout出力表示しています。
ソーラー「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;
と取り込んでいると
そういうわけなんだねっ」
てんC「はい。この配列宣言int hairetu[];
を自作関数の()の部分に引数として記入し
main関数内で変数宣言された別の配列内の配列変数のアドレス情報を
この自作関数の引数となった
配列宣言int hairetu[]
に参照渡し(ポインタ渡し)することができます。」
ソーラー「ええ????
はへ?
なんのことかわからない?・?・・・」
マックス「俺もだぁぁぁぁぁぁぁぁぁ」
青空にシャウトする。
てんC「それでは
配列を引数とした自作関数を使って構成された
次のプログラムをみていきましょう。」
#include <iostream>
using namespace std;
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() {
int newhairetu[5] = { 1,2,3,4,5 };
newmadefunction(newhairetu);
/*配列newhairetuのアドレスを格納している
ポインタ変数newhairetuが自作関数の引数の
int hairetu[]に代入されています*/
int j;
for (j = 0; j<5; j++)
cout << newhairetu[j]<< "\n";
return 0;
}
ビルド実行結果
2
4
6
8
10
てんC「このプログラムでは
冒頭の自作関数宣言で自作関数newmadefunctionの引数を
配列とするためにnewmadefunction()の()内で
配列宣言int hairetu[]をおこなっています
そしてmain関数内で
新しくつくられた配列newhairetu
のアドレスを格納しているポインタ変数newhairetu
を自作関数
newmadefunction(int hairetu[])内の引数である
int hairetu[]に代入しています・・・・・・
ここで注目するべきところは
やはり
自作関数newmadefunction(int hairetu[])の
引数 int hairetu[]に
配列newhairetuのアドレスを格納している
ポインタ変数newhairetuを
代入しているところです。」
ソーラー「
main関数内で変数宣言された配列newhairetuのアドレスを格納している
ポインタ変数newhairetuを
自作関数の引数である
int hairetu[]に
代入する???
どういうこと?
さすがに無理ぃぃぃぃぃぃ~~~
もう意味不明すぎてツッコミできません
配列にポインタ変数を代入する?
それはできないんじゃないかな?」
てんC「ここでなぜ
ポインタ変数newhairetuを自作関数の引数に代入するのに
配列宣言int hairetu[]が行われているのか
🐣なぜ そのようにC言語の作者は設定したのか 🐣
(この仕組みはC言語から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^)/
やっぱり 読者のみなさんもそう思うよね」
てんC「ですが
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
を代入していることになると思われます。」
ソーラー「なんだってぇ~」
マックス「なるほどな。」
てんC「
ですから
C言語の作者さんが
自作関数の()内はint hairetu[]でいいや
と設定したのも自然なことだったかもしれないですね」
ソーラー「そ、そうだね」
感嘆するソーラー。
もうなんか いま ラーメン作ってます。私
ぶっとんでます
solarplexussより
てんC
「
このようにして
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
まさに 参照渡し(ポインタ渡し)が行われたときのパターンだったね」
てんC「今のプログラムでは
main関数内で
自作関数newmadefunction(int hairetu[]);
に
main関数内で定義された配列のアドレスを
格納しているポインタ変数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
に代入しているといえるかもしれないね。」
てんC「はい
そして
このプログラムにおいて
main関数内で配列宣言された
配列newhairetu[]の
アドレスを格納したポインタ変数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^)/💖したってわけだね」
てんC
「ここで
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言語でもC++言語でも用意されているんだね。
別の言い方をすると
配列宣言
int hairetu[]によって
配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
(int hairetu[]には配列newhairetu[5]のアドレスを格納しているポインタ変数が代入されます
そして
生成される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
に代入されているといえるかな」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます