C言語講座7回目、今回は構造体の活用方法です。
構造体を関数の引数で使うと、プログラムの修正も楽になります。
C言語で構造体を関数の引数にする
構造体へのアクセスパターン
Humanという構造体を定義します。
struct Human {
char szName[64]; /* 名前 */
int iAge; /* 年齢 */
}
アクセス方法は複数あります。
(1)ポインタで定義
struct Human *pHuman;
除法へのアクセスは->で行います。
pHuman->szName;
pHumanそのものは、ポインタなので、実際にアクセスするためには、領域が必要です。
pHuman = malloc(sizeof(struct Human));
strcpy(pHuman->szName, "YAMADA");
(2)インスタンスとして定義
struct Human sHuman;
インスタンスからの取り出しは、"."を使います。
sHuman.szName;
(3)ポインタの中身へのアクセス
(*pHuman).szName; /* 括弧は、* よりも . の方が結びつきが強いため必要 */
ポインタの指し示している中身そのものを取り出すのは、アスタリスクで可能というC言語のルールを適用できます。
構造体の使い道
さて、構造体はどんな場合に使えばよいのでしょうか
(1)情報としてひとまとまりの意味を持つもの
例えば、名前と性別、年齢をまとめて、人間という構造体にしてしまう等。
プログラムとしてわかりやすくなります。
(2)関数に数多くの情報を渡す必要がある場合
構造体にまとめると渡す情報が増えても、構造体の定義を変更するだけで対応できるケースがあります。
(1)は、構造体を使うそもそもの理由なので、ここでは(2)について補足します。
func1という関数を作っていて、これを数多くの個所で呼び出していたとします。
まずは、構造体を使用しない例)です。
int func1(int iVal1, int iVal2) { return iVal1 + iVal2; } main() { .... i1 = 1; i2 = 2; iAns = func1(i1, i2); .... iAns = func1(i1, i2); .... }
次に、構造体を使用した例になります。
/* tinfo.h */ typedef struct _tagInfo { int iVal1; int iVal2; } TINFO; #include "tinfo.h" int func1(TINFO* pInfo) { return pInfo->iVal1 + pInfo->iVal2; } #include "tinfo.h" main() { TINFO t; .... t.iVal1 = 1; t.iVal2 = 2; iAns = func1(&t); /* <= 構造体のアドレスを渡すときは、&をつけて */ .... iAns = func1(&t); .... }
3つの値の計算が必要になったとします。
/*構造体を使わない例 */ int func1(int iVal1, int iVal2, int iVal3) { return iVal1 + iVal2 + iVal3; } /*構造体を使用した例 */ typedef struct _tagInfo { int iVal1; int iVal2; int iVal3; } TINFO; int func1(TINFO* pInfo) { return pInfo->iVal1 + pInfo->iVal2 + pInfo->iVal3; }
構造体を使用しない場合の方が、修正がすくなく見えます。
しかし実際には、構造体を使用していない場合、その関数を呼び出しているすべての個所で引数を修正する必要があります。呼び出す箇所が多ければ多いほど、修正は大変になるし、ミスが増えるリスクも増加します。
更に、引数が多いと記述するのも長くなってきます。
将来の拡張も考慮して、皆で使用する共通関数などには、意味をもった構造体をつくり、それを引数にしておくと便利です。
今回はここまで。
C言語の話は、この後も何回かに分けて投稿しますので、興味のある方は引き続きよろしくお願いします。