このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
座標のように、複数の値を一つのものとして扱いたい場合があります。 C 言語では構造体という仕組みで扱うことができます。 まず、構造体の型を決め、その型の変数を宣言します。 型を決めるには struct 宣言 をします。 struct の後に、構造体の名前を決め、その後にメンバーの宣言のブロック({} で括られたもの)が来て、最後にセミコロン(;)で終了します。 メンバーの宣言は変数宣言と同じ形になりますが、変数が宣言されるわけでは ないの注意が必要です。 例えば座標の構造体の型は次のように宣言されます。これは変数宣言ではなく、 型の宣言です。 従ってこれだけで変数が使用できるわけではありません。
struct point {
double x;
double y;
};
このようにすると point という構造体の型が作られます。 point は構造体の型であって、変数ではありません。 point 型の変数 p と q を宣言するには次のようにします。
struct point p,q;
宣言した変数は次のように使います。
p.x=1.0;
printf("%f\n",p.y);
q=p;
printf("%f\n",q.x);
struct point p={1.0,2.0};
/* p という変数が作られ、 p.x に 1.0, p.y に 2.0 が代入される */
なお、二つの構造体の変数が一致しているかどうかは == で調べられませんの で、一つ一つ要素を比べるしかありません。
構造体 A を作っても、変数宣言は struct A x;
とするしかあ
りません。
(C++ ではちゃんと A x; と書けますが……)
そのため struct を書かなくするために typedef という宣言があります。
typedef struct point {
double x;
double y;
} POINT;
と宣言すると、この宣言以降、 struct point の代わりに POINT と書けば済 むようになります。 変数宣言は次のようになります。
POINT p,q;
/* point 型の変数 p と q が宣言される */
POINT r={1.0,2.0};
/* point 型の変数 r が宣言され、 r.x に 1.0, r.y に 2.0 が代入される。 */
これは関数の定義でも使えます。
なお、複数のファイルで構造体を使う場合、構造体の宣言がそれぞれ必要です ので、ヘッダファイルに入れられます。
構造体のポインタの宣言は通常のポインタと同様です。
POINT *p;
POINT q={1.0,2.0};
q の番地を p に入れるのも同様です。
p=&q;
p の指す構造体の要素をアクセスする場合、 (*p).x
とも書け
ますが、これを p->x
と書くこともできます。
構造体の配列の取り扱いは、通常の配列の取り扱いと同様です。
POINT p[5];
int i;
for(i=0; i<5 ; i++){
p[i].x=0.0;
p[i].y=1.0;
}
構造体は普通の変数と同様に関数と値をやりとりできます。 つまり、特にポインタなどを使用しなくてもよいということです。
---------------p.h----------------typedef struct p { int x; int y; } POINT; POINT sub(POINT p);
---------------sub.c--------------#include "p.h" POINT sub(POINT p){ p.x--; p.y++; return p; }
---------------main.c------------- #include <stdio.h> #include "p.h" main(){ POINT p={1,2},q; q=sub(p); printf("%d\n%d\n",q.x,q.y); }
構造体 POINT を次のように定義します。
typedef struct point {
double x;
double y;
} POINT;
POINT 型の引数をもらい、原点からの距離を double 型で返す関数 distance を作りなさい。 そして、以下の main 関数によりその関数をテストしなさい。
----point.h----typedef struct point { double x; double y; } POINT; double distance(POINT p);
----main.c---- #include <stdio.h> #include "point.h" main(){ POINT p={3.0,4.0}; printf("点 %f, %f と原点の距離は %f です。\n",p.x,p.y,distance(p)); } ----distance.c----#include "point.h" double distance(POINT p){ /* この部分を書く (必要ならヘッダファイルを追加する)*/ }
POINT 型のポインタを引数とし、その引数の x 座標、y 座標とも 1/2 にする
関数 void half(POINT *p)
を作りなさい。
そして、以下の main 関数によりその関数をテストしなさい。
----point.h----typedef struct point { double x; double y; } POINT; void half(POINT *p);
----main.c---- #include <stdio.h> #include "point.h" main(){ POINT p={6.0,8.0}; printf("最初の点は %f, %f です。",p.x,p.y); half(&p); printf("半分の位置は %f, %f です。",p.x,p.y); } ----half.c----#include "point.h" void half(POINT *p){ /* この部分を書く */ }