天国にいけるC言語入門 ヘキサ構造体 ver5.2130
main関数内で定義された配列に格納されている数値データを自作関数を使って変更してみましょう。自作関数の引数が(int* hairetu)となっている場合🌞
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
に代入されているといえるかな」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます