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