【c言語+DXライブラリ】構造体を引数として渡す


 C言語の勉強としてシューティングゲームを作っていく中で知りました。

 構造体を引数として渡すことの何が嬉しいのかと、その使い方を書き残しておきます。

構造体を引数として渡せると何が嬉しいのか

 簡潔になるところです。

 構造体を作らずに書いたプログラムと、構造体を書いたプログラムを比較すると、構造体を書かないプログラムはめちゃくちゃ長いうえに、読みにくいです。

構造体なら読みやすく、一つ一つ指定しなくて済むため訂正も簡単です。新しい要素を足すときも簡単で、shoot4をすべて作る、なんてことをせずになくて済みます。

構造体にしてしまえば自分の手間も省け、それを読む相手の負担も避けられます。

プログラムを貼っておきます。まずは構造体を用いないで書くと…

notkouzou.c
//変数宣言(新しい変数のたびに要素をすべて宣言)
int Shoot1_graph = ;
int Shoot1_x;
int Shoot1_y;
int Shoot1_flag;

int Shoot2_graph = ;
int Shoot2_x;
int Shoot2_y;
int Shoot2_flag;

int Shoot3_graph = ;
int Shoot3_x;
int Shoot3_y;
int Shoot3_flag;

int Shoot4_graph = ;
int Shoot4_x;
int Shoot4_y;
int Shoot4_flag;

//この先が引数

int spaceKey(int Shoot1_graph = ,int Shoot1_x,int Shoot1_y,int Shoot1_flag){
//略

きゃー!
以下、構造体を用いたコードです。

kouzou.c
//構造体宣言
struct Shoot {
    int graph;
    int x;
    int y;
    int flag;
};

//構造体に名前をつける(いくつでも可)
Shoot myshoot[] = { { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 },
                  { LoadGraph("png/shot_tama.png") ,po.x, po.y, 0 }}

//この先が引数

int spaceKey(Shoot* myshoot1, Shoot* myshoot2, Shoot* myshoot3) {
}

わ、なんかいい!

構造体を引数として渡す方法

プログラム例を貼ります。

sample.c
//①
struct Player {
    int graph;
    int x;
    int y;
    int damage;
};

//②
int move(Player *po);

int main(void){
    //③
    Player po = { LoadGraph("xx.png") , 300, 300, 4 };

    //④
    move(&po);
}

//⑤
int move(Player *po) {
//処理
    return 0;
}

①構造体を宣言します。

②関数を宣言します(moveとする)。「*po」と書くことで「po構造体のアドレスを引数として受け取るmove関数があるよ」と宣言しています。

③構造体の名前を決め(poとする)、要素を指定します。

④move関数を呼び出します。ここで、「&po」とすることで、move関数にpo構造体のアドレスを渡します。(*poではありません)

⑤move関数が「*po」でpo構造体のアドレスをもらい、move関数の処理を書きます。この関数内で、構造体の中身は全て使用できます。

!注意!

move関数の中では、Player.xは使えません。Player->xとして使います。(詳しくはアロー演算子で検索)

まとめ

 構造体を、ポインタを使用して引数として渡すことを「参照渡し」と呼ぶそうです。

 先輩にプログラムを見てもらう機会が一度だけあり、その時に「参照渡しできるんだ」と言われた時「参照渡してなんですか?」と返して呆れられました。単語大事。