今日やること
前回は列挙型と再帰について学びました。今回は構造体について勉強していきます。 今回が最後の回となる予定なので頑張っていきましょう。
構造体
構造体とは複数のデータ(変数)を1つにまとめて、1つのオブジェクトとして扱うようなことを言います。 定義は以下のように書きます。
struct タグ名 {
型 メンバ1;
型 メンバ2;
型 メンバ3;
.
.
.
型 メンバn;
}構造体変数;
//例
struct SEnemy{
char name[32];
int hp;
int mp;
int atk;
int def;
int spd;
int exp;
}slime;
構造体変数はここで宣言しなくても大丈夫です。 別の場所で構造体変数を作りたいときは下のように書きます。
struct タグ名 変数名;
//例
struct SEnemy slime;
typdefでstruct タグ名に名前を付けるようなことができます。例えば
typedef struct SEnemy{
char name[32];
int hp;
int mp;
int atk;
int def;
int spd;
int exp;
}enemy;
enemy slime;
のようにstruct SEnemy をenemyのみで表すことでができます。
この、enemyはSEnemy型の変数ではなく、struct Senemyを1語で表したもののような意味となります。
構造体のメンバにアクセスしたい場合は以下のように書きます。
構造体変数名.メンバ;
//例
slime.hp=10;
構造体を丸ごとコピーする場合は下のように代入するようにして書けば大丈夫です。
構造体変数名=構造体変数名;
//例
struct SEnemy slime,slime_besu;
slime.mp=20;
slimebesu=slime;
関数の引数として取ることもできます。例えば、上のSEnemy型変数がもつメンバのデータを表示する関数は以下のように書きます。
void Print_Enemy_Data(struct SEnemy enemy){
printf("名前:%s\n",enemy.name);
printf("HP:%d MP:%d\n", enemy.hp , enemy.mp );
printf("ATK:%d DEF:%d\n", enemy.atk , enemy.def );
printf("SPD:%d EXP:%d\n", enemy.spd, enemy.exp );
}
変数を別々に書くよりもまとまりがあって扱いやすいと思います。
構造体はポインタで扱うことでができます。その場合要素の参照は.の代わりに->を使いますできます。
例としてダメージ計算を行う関数を書きます。
int Damege(int atc ,int level ,struct SEnemy *enemy){
int damage=atc*level/enemy->def;
enemy->hp-=damage;
if(enemy->hp<=0)return 0;
else return 1;
}
enemy->hpの代わりに、(*enemy).hpと書くこともできます。
練習しよう
練習として以下の問題を解きましょう。
1. 引数x(自然数)をとり、[logx](logx以下の最大の整数)の値を返す関数を再帰を用いて書け。
2. 実部と虚部の値をもつ構造体SComplexを作れ。
3. SComplex型の変数を引数cとしてとり、cが意味する値を "(実部)+(虚部)i" と表示する関数を書け。
4. SComplex型の2つの変数を引数c1,c2としてとり、c1c2の結果を構造体SComplexとして返す関数を書け。
5. SComplex型のポインタc1と変数c2を引数にとり、c1の実体にc2の値を足す関数を書け。
最後に
今日の内容はこれで終わりです。これで重要となるところは一通りできたと思います。 ファイル入出力や乱数などC言語には他の機能もあるの興味がある人は調べて見て下さい。 また、他の言語を学ぶのも良いかもしれません。プログラムの練習がしたいという人はこれからやっていく予定の 競プロ勉強会に参加してみて下さい。では、今までC言語勉強会お疲れ様でした。