構造体型の配列をつかって複数のキャラクターのステータスデータを2倍に変更して表示するときの利点はfor文を使ってprintf命令文をまとめあげることができるという点にあります

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

👇

#include <stdio.h>


typedef struct CharacterStatusData

{

int HP;

int MP;

int AP;

int TP;

}CharacterStatusData;


void CharacterStatusData2bai(CharacterStatusData*pta){


pta->HP=2*pta->HP;

pta->MP=2*pta->MP;

pta->AP=2*pta->AP;

pta->TP=2*pta->TP;


}


int main(void)

{


CharacterStatusData str[2]={{10,12,20,15},{100,120,38,25}};


int i;


for(i=0;i<2;i++){


printf("%d\n" ,str[i].HP);

printf("%d\n" ,str[i].MP);

printf("%d\n" ,str[i].AP);

printf("%d\n" ,str[i].TP);

}


for(i=0;i<2;i++){


CharacterStatusData2bai(&str[i]);


printf("%d\n" ,str[i].HP);

printf("%d\n" ,str[i].MP);

printf("%d\n" ,str[i].AP);

printf("%d\n" ,str[i].TP);

}

return 0;

}


コンパイル結果


10

12

20

15

100

120

38

25

20

24

40

30

200

240

76

50


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


自作関数CharacterStatusData2bai(CharacterStatusData* pta)


の引数であるCharacterStatusData*型のポインタ変数ptaに


配列変数str[0]のメンバ変数

str[0].HP

str[0].MP

str[0].AP

str[0].TP

のアドレスを代表する


&str[0]をつかって



配列変数str[1]のメンバ変数

str[1].HP

str[1].MP

str[1].AP

str[1].TP

のアドレスを代表する


&str[1]をつかって


参照渡ししていました。


その方法の他に


実は


&str[0]の代わりに


str[0].HP

str[0].MP

str[0].AP

str[0].TP


の4つのアドレスを代表しているポインタ変数


str


&str[1]の代わりに


str[1].HP

str[1].MP

str[1].AP

str[1].TP


の4つのアドレスを代表しているポインタ変数


str+1


をつかって

str[0].HP

str[0].MP

str[0].AP

str[0].TP


str[1].HP

str[1].MP

str[1].AP

str[1].TP


のアドレスを


自作関数 CharacterStatusData2bai(CharacterStatusData* pta)


の引数であるCharacterStatusData*pta


つまり


CharacterStatusData*型の


ポインタ変数ptaに参照渡し(ポインタ渡し)することができます



プログラムは以下のように変更されます。



#include <stdio.h>


typedef struct CharacterStatusData

{

int HP;

int MP;

int AP;

int TP;

}CharacterStatusData;


void CharacterStatusData2bai(CharacterStatusData*pta){


pta->HP=2*pta->HP;

pta->MP=2*pta->MP;

pta->AP=2*pta->AP;

pta->TP=2*pta->TP;


}


int main(void)

{


CharacterStatusData str[2]={{10,12,20,15},{100,120,38,25}};


printf("%d\n" ,str[0].HP);

printf("%d\n" ,str[0].MP);

printf("%d\n" ,str[0].AP);

printf("%d\n" ,str[0].TP);


printf("%d\n" ,str[1].HP);

printf("%d\n" ,str[1].MP);

printf("%d\n" ,str[1].AP);

printf("%d\n" ,str[1].TP);


CharacterStatusData2bai(str);


printf("%d\n" ,str[0].HP);

printf("%d\n" ,str[0].MP);

printf("%d\n" ,str[0].AP);

printf("%d\n" ,str[0].TP);


CharacterStatusData2bai(str+1);


printf("%d\n" ,str[1].HP);

printf("%d\n" ,str[1].MP);

printf("%d\n" ,str[1].AP);

printf("%d\n" ,str[1].TP);



return 0;

}

コンパイル結果

10

12

20

15

100

120

38

25

20

24

40

30

200

240

76

50


ソーラー「さらに



for文につかうことによりプログラムを簡略化すると


#include <stdio.h>


typedef struct CharacterStatusData

{

int HP;

int MP;

int AP;

int TP;

}CharacterStatusData;


void CharacterStatusData2bai(CharacterStatusData* pta) {


pta->HP = 2*pta->HP;

pta->MP = 2*pta->MP;

pta->AP = 2*pta->AP;

pta->TP = 2*pta->TP;


}


int main(void)

{


CharacterStatusData str[2] = { { 10,12,20,15 },{ 100,120,38,25 } };


int i = 0;


for (i = 0; i <= 1; i++) {


printf("%d\n", str[i].HP);

printf("%d\n", str[i].MP);

printf("%d\n", str[i].AP);

printf("%d\n", str[i].TP);

}



for (i = 0; i <= 1; i++) {


CharacterStatusData2bai(str + i);


printf("%d\n", str[i].HP);

printf("%d\n", str[i].MP);

printf("%d\n", str[i].AP);

printf("%d\n", str[i].TP);

}


return 0;

}


コンパイル結果


10

12

20

15

100

120

38

25

20

24

40

30

200

240

76

50

となります


このように

配列変数のメンバ変数


str[0].HP

str[0].MP

str[0].AP

str[0].TP


str[1].HP

str[1].MP

str[1].AP

str[1].TP


のアドレスを代表して

&str[0]

&str[1]


もしくは


str

str+1



自作関数の引数であるCharacterStatusData*型のポインタ変数に参照渡し(ポインタ渡し)できるんだ 


構造体型の配列の優れたところなんだね



変数iを用いて


&str[i]


と表記しておけば


変数iの数値を0,1と変えることにより


&str[0]

&str[1]


のアドレスが表現できるから



命令文


CharacterStatusData2bai(&str[0]);


printf("%d\n", str[0].HP);

printf("%d\n", str[0].MP);

printf("%d\n", str[0].AP);

printf("%d\n", str[0].TP);


CharacterStatusData2bai(&str[1]);


printf("%d\n", str[1].HP);

printf("%d\n", str[1].MP);

printf("%d\n", str[1].AP);

printf("%d\n", str[1].TP);



for文をもちいて


for(i=0;i<2;i++){


CharacterStatusData2bai(&str[i]);


printf("%d\n" ,str[i].HP);

printf("%d\n" ,str[i].MP);

printf("%d\n" ,str[i].AP);

printf("%d\n" ,str[i].TP);

}


のように

まとめることができるんだね


もしくは


変数iを用いて


str+i


と表記し


変数iの数値を0,1と変えることにより


str (&str[0]のアドレスを格納したポインタ変数)

str+1(&str[1]のアドレスを格納したポインタ変数)


を表現することができるので


&str[0]

&str[1]


の代わりに


str (&str[0]のアドレスを格納したポインタ変数)

str+1(&str[1]のアドレスを格納したポインタ変数)


自作関数

void CharacterStatusData2bai(CharacterStatusData* pta)


のCharacterStatusData*型のポインタ変数に代入することにすれば




CharacterStatusData2bai(str );


printf("%d\n", (str)->HP);

printf("%d\n", (str)->MP);

printf("%d\n", (str)->AP);

printf("%d\n", (str)->TP);

/*↑この部分はもしくは

printf("%d\n", str[0].HP);

printf("%d\n", str[0].MP);

printf("%d\n", str[0].AP);

printf("%d\n", str[0].TP);


と表現できます。

*/


CharacterStatusData2bai(str+1 );


printf("%d\n", (str+1)->HP);

printf("%d\n", (str+1)->MP);

printf("%d\n", (str+1)->AP);

printf("%d\n", (str+1)->TP);


/*↑この部分はもしくは


printf("%d\n", str[1].HP);

printf("%d\n", str[1].MP);

printf("%d\n", str[1].AP);

printf("%d\n", str[1].TP);


と表現できます。

*/



の部分は


for文をもちいて


for (i = 0; i <= 1; i++) {


CharacterStatusData2bai(str + i);


printf("%d\n", (str+i)->HP);

printf("%d\n", (str+i)->MP);

printf("%d\n", (str+i)->AP);

printf("%d\n", (str+i)->TP);

}


もしくは


for(i=0;i<2;i++){


CharacterStatusData2bai(str + i);


printf("%d\n", str[i].HP);

printf("%d\n", str[i].MP);

printf("%d\n", str[i].AP);

printf("%d\n", str[i].TP);

}


のように


まとめることができるんだね。


対して


character1のステータスデータ

10

12

20

15

character2のステータスデータ

100

120

38

25



2倍にするのに


構造体CharacterStatusDataの

構造体変数

character1StatusData

character2StatusData

を使った場合では


character1StatusData.HP

character1StatusData.MP

character1StatusData.AP

character1StatusData.TP


character2StatusData.HP

character2StatusData.MP

character2StatusData.AP

character2StatusData.TP

のアドレス

それぞれ

&character1StatusData

&character2StatusData


によって代表されることになります


そのアドレスを


自作関数


void CharacterStatusData2bai(CharacterStatusData* pta)



引数となっている


CharacterStatusData*型のポインタ変数ptaに代入することになるので


プログラムは次のようになります。


#include <iostream>


using namespace std;


typedef struct CharacterStatusData {


int HP;

int MP;

int AP;

int TP;


}CharacterStatusData;


void CharacterStatusData2bai(CharacterStatusData* pta) {


pta->HP = 2*pta->HP;

pta->MP = 2*pta->MP;

pta->AP = 2*pta->AP;

pta->TP = 2*pta->TP;

}


int main(){


CharacterStatusData character1StatusData = { 10,12,20,15 };

CharacterStatusData character2StatusData ={ 100,120,38,25 };


printf("%d\n", character1StatusData .HP) << "\n";

printf("%d\n", character1StatusData .MP) << "\n";

printf("%d\n", character1StatusData .AP)<< "\n";

printf("%d\n",character1StatusData .TP) << "\n";


printf("%d\n", character2StatusData .HP) << "\n";

printf("%d\n", character2StatusData .MP) << "\n";

printf("%d\n", character2StatusData .AP)<< "\n";

printf("%d\n",character2StatusData .TP) << "\n";


CharacterStatusData2bai(&character1StatusData);


printf("%d\n", character1StatusData .HP) << "\n";

printf("%d\n", character1StatusData .MP) << "\n";

printf("%d\n", character1StatusData .AP)<< "\n";

printf("%d\n",character1StatusData .TP) << "\n";


CharacterStatusData2bai(&character2StatusData);


printf("%d\n", character2StatusData .HP) << "\n";

printf("%d\n", character2StatusData .MP) << "\n";

printf("%d\n", character2StatusData .AP)<< "\n";

printf("%d\n",character2StatusData .TP) << "\n";

return 0;


}


ビルド実行結果


10

12

20

15

100

120

38

25

20

24

40

30

200

240

76

50


ソーラー「


CharacterStatusData2bai(&character1StatusData);


printf("%d\n", character1StatusData .HP) << "\n";

printf("%d\n", character1StatusData .MP) << "\n";

printf("%d\n", character1StatusData .AP)<< "\n";

printf("%d\n",character1StatusData .TP) << "\n";


CharacterStatusData2bai(&character2StatusData);


printf("%d\n", character2StatusData .HP) << "\n";

printf("%d\n", character2StatusData .MP) << "\n";

printf("%d\n", character2StatusData .AP)<< "\n";

printf("%d\n",character2StatusData .TP) << "\n";


の部分は


数値1

数値2



character1StatusData

character2StatusData

のように


構造体変数の名前の中に埋め込まれているため


変数iの数値を変化させることにより


character[i]StatusDataを用いて


character1StatusData

character2StatusDataを表現することができず


for文をもちいて命令文をまとめあげることができないね。



C言語の作者さんも


ここに注目して


構造体型の配列をつくったんじゃないかな?


配列ときたら


for文をつかって命令文をまとめあげることができる\(^o^)/


ここはポイントだね。」



🌞      🌞     🌞


この例のように


for文と


構造体CharacterStatusData型の配列宣言CharacterStatusData str[i];


を用いることにより


配列変数のメンバ変数

str[0].HP

str[0].MP

str[0].AP

str[0].TP


str[1].HP

str[1].MP

str[1].AP

str[1].TP


str[i].HP

str[i].MP

str[i].AP

str[i].TP


が生成されます


そのとき


配列変数

str[i].HP

str[i].MP

str[i].AP

str[i].TP


のアドレスを代表しているポインタ変数は


str+iとなっています


そして


str[i].HP

str[i].MP

str[i].AP

str[i].TP


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


ポインタ変数

str+i


にアロー演算子を用いた


(str+i)->HP

(str+i)->MP

(str+i)->AP

(str+i)->TP


表現することができます。



               solarplexussより



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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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