構造体とはchar型やint型、float型のような異なったデータ型をまとめて扱いたいときに使うものです。
型枠の宣言はどこに書いてもいいですが、一般的にはヘッダファイルやプリプロセッサの下からプロトタイプ宣言までの間に書くのが推奨されています。
また、構造体の中の変数をメンバ変数と呼びます。
書き方は以下の通りです。
struct 構造体の種類名{
型名 メンバ変数;
};
struct Name{
int i;
char c;
float f;
};
構造体の宣言は普通のデータ型と似た感じで使います。書き方としてはstruct 構造体の種類の名前 この宣言でできる構造体の変数名といった感じです。
構造体の種類の名前でどの構造体の呼び出しかを示し、次のこの宣言でできる構造体の変数名で他のものと区別します。
上の例で例を示すと、struct Name 好きな変数名;です。
構造体の参照は構造体の変数名.メンバ変数名で行えます。
.のことをドット演算子(メンバアクセス演算子)と呼びます。
ドット演算子とは構造体のメンバへのアクセスをするために使う演算子です。そのためにメンバアクセス演算子とも呼びます。(C言語以外では別の意味があったりもしますが、初級C言語ゼミなので割愛させてもらいます。)
では、構造体を使った例をみてみましょう。#include<stdio.h> #include<stdlib.h> #define MAX 256 //構造体の型枠の宣言 struct Data{ char name[MAX]; int age; }; int main(void); int main(void){ struct Data data; //構造体の宣言 char a[MAX]; printf("名前 : "); fgets(data.name, MAX, stdin); printf("年齢 :"); fgets(a, MAX, stdin); data.age = atoi(a); printf("名前: %s年齢: %d歳\n", data.name, data.age); return(0); }
名前 : Tako 年齢 : 19 名前: Tako 年齢: 19歳
構造体同士の代入は非常に単純で、構造体の変数名(代入する側) = 構造体の変数名(代入される側)で全て代入できます。 しかし、別の種類の構造体へは代入できません。同じ種類の構造体でなければなりません。
以下に例を示します。#include<stdio.h> #include<stdlib.h> #define MAX 256 struct Data{ char name[MAX]; int age; }; int main(void); int main(void){ struct Data data, data2; char a[MAX]; printf("名前 : "); fgets(data.name, MAX, stdin); printf("年齢 : "); fgets(a, MAX, stdin); data.age = atoi(a); data2 = data; //構造体同士の代入 printf("名前: %s年齢: %d歳\n", data2.name, data2.age); return(0); }
名前 : しもぶ〜 年齢 : 0 名前: しもぶ〜 年齢: 0歳
構造体は配列として宣言することもできます。
構造体の初期化は{0}のように行います。配列の数が1つの時は同じですが、メンバ変数が配列をもっているときは{{0}}のように書きます。
構造体は関数の引数に渡すことも返り値として返すこともできます。
以下に例を示します。#include<stdio.h> #include<stdlib.h> #define MAX 256 #define NUM_MAX 4 #define B_MAX 10 struct Data{ char name[MAX]; char bt[B_MAX]; }; int main(void); struct Data input_data(struct Data data); void print_data(struct Data data[NUM_MAX]); int main(void){ struct Data data[NUM_MAX] = {{0}}; //構造体の配列と初期化 int i; for(i = 0; i < NUM_MAX; i++){ data[i] = input_data(data[i]); //構造体の引数渡し } print_data(data); //構造体すべてを引数から渡す return(0); } struct Data input_data(struct Data data){ printf("Name?\n> "); fgets(data.name, MAX, stdin); printf("BloodType?\n> "); fgets(data.bt, B_MAX, stdin); return(data); } void print_data(struct Data data[NUM_MAX]){ int i; for(i = 0; i < NUM_MAX; i++){ printf("Name : %s", data[i].name); printf("BloodType : %s", data[i].bt); } }
Name? > しもぶ〜 BloodType? > しも Name? > Sitiyan BloodType? > A Name? > Y・ハルヒ BloodType? > A Name? > RCC 太郎 BloodType? > O Name : しもぶ〜 BloodType : しも Name : Sitiyan BloodType : A Name : Y・ハルヒ BloodType : A Name : RCC 太郎 BloodType : O
typedefとは既存の型に新しい名前をつけることのできるものです。プログラムを書くのを少し楽にしてくれます。
書き方はtypedef 既存の型名 新しい型名です。また、構造体の時は typedef struct 構造体の種類の名前{ メンバ }新しい型名;と書きます。
typedef int INTEGER;
こう書くことで、int i;とINTEGER i;が同じ意味になります。
また、typedef char string;
そして、もっともtypedefを使うのが構造体です。では例です。
typedef struct PC{ char PC_name[MAX]; char mouse_name[MAX]; char keybord_name[MAX]; char printer_name[MAX]; char scanner_name[MAX]; float display_size; int usb_port; }PC;
列挙体とは構造体は変数をメンバとしておきましたが、その反対で定数をメンバとしておきます。まずは列挙体の型枠の例を示します。
enum{
ZERO,
ONE,
TWO
};
enum{
ZERO = 1,
ONE,
TWO
};
enum TOWN{
FIRST_TOWN,
NEXT_TOWN,
LAST_TOWN
};
#include<stdio.h> #include<stdlib.h> #define MAX 256 enum TOP{ NEW, LOAD, QUIT }; enum BOOL{ FALSE, TRUE }; int main(void); int main(void){ char select[MAX]; int flag = FALSE; while(TRUE){ printf("0:NEW GAME 1:LOAD GAME 2:QUIT\n"); printf("select :"); fgets(select, MAX, stdin); switch(atoi(select)){ case NEW: printf("初めから始めます。\n\n"); break; case LOAD: printf("データをロードします。\n\n"); break; case QUIT: printf("終了します。\n"); flag = TRUE; break; } if(flag == TRUE)break; } return(0); }
0:NEW GAME 1:LOAD GAME 2:QUIT select: 0 初めから始めます。 0:NEW GAME 1:LOAD GAME 2:QUIT select: 1 データをロードします。 0:NEW GAME 1:LOAD GAME 2:QUIT select: 2 終了します。
リダイレクションとは、標準入力が必要なプログラムでどのように入力するか記述したファイルを使って、
自分で入力する大変さをなくすことができるもののことです。
例えば、fgets関数から3回標準入力するプログラム(○○.exe)があった場合、
a、b、cと入力する代わりに、ファイル(.txtや.c等)に以下のように記述するとします。
a b c
こう書かれたファイル(△△.txt)を実行するプログラム(○○.exe)で使う場合、コマンドプロンプト、またはCPadの上のコマンド欄に
○○.exe < △△.txt
現在のサークル員のデータを管理したいので管理プログラムを構造体と列挙体を用いて作成してください。(必要な項目:回生、本名、アカウント…etc)
このプログラムには以下の機能がある。
基本問題の管理プログラムに以下の機能を追加してください。
次回はポインタについて説明します。