構造体の配列をつかって複数のキャラクターのステータスデータを2倍に変更して表示するときの利点は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;


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;

}


コンパイル結果


20

24

40

30

200

240

76

50


アレサ「


自作関数 CharacterStatusData2bai(CharacterStatusData*pta)


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


str[0].HP

str[0].MP

str[0].AP

str[0].TP

のアドレスを


&str[0]をつかって


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)


の引数であるポインタ変数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}};


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;

}

コンパイル結果


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++) {


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;

}


コンパイル結果


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



自作関数の引数であるポインタ変数にポインタ渡しできるのが 


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



変数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+1


と表記し


変数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とcharacter2のステータスデータを


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


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;


}


ビルド実行結果

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^)/


ここはポイントだね。」



🌞      🌞     🌞


この例のように


構造体の配列宣言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で共有
  • はてなブックマークでブックマーク

作者を応援しよう!

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

応援したユーザー

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