このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
座標のように、複数の値を一つのものとして扱いたい場合があります。 C 言語では構造体という仕組みで扱うことができます。 まず、構造体の型を決め、その型の変数を宣言します。 例えば座標の構造体の型は次のように宣言されます(最後のセミコロン(;)は必 須です)。これは変数宣言ではなく、型の宣言です。
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};
なお、二つの構造体の変数が一致しているかどうかは == で調べられませんの で、一つ一つ要素を比べるしかありません。
構造体 A を作っても、変数宣言は struct A x;
とするしかあ
りません。
(C++ ではちゃんと A x; と書けますが……)
そのため struct を書かなくするために typedef という宣言があります。
typedef struct point {
double x;
double y;
} POINT;
と宣言すると、この宣言以降、 struct point の代わりに POINT と書けば済 むようになります。 変数宣言は次のようになります。
POINT x,y;
POINT z={1.0,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;
}
構造体は普通の変数と同様に関数と値をやりとりできます。 つまり、特にポインタなどを使用しなくてもよいということです。
#include <stdio.h>
typedef struct p {
int x;
int y;
} POINT;
POINT sub(POINT p){
p.x--;
p.y++;
return p;
}
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 関数によりその関数をテストしなさい。
#include <stdio.h>
typedef struct point {
double x;
double y;
} POINT;
double distance(POINT p);
main(){
POINT p={3.0,4.0};
printf("点 %f, %f と原点の距離は %f です。\n",p.x,p.y,distance(p));
}
ここで、 double distance(POINT p);
はこのファイルで
distance という関数を使用することを宣言する文です。
このように関数の使用を宣言する文をプロトタイプと言います。
distance 関数が同じプロジェクトの別ファイルである場合は、このように関
数を使用するファイル内でプロトタイプの宣言が必要になります。
POINT 型のポインタを引数とし、その引数の x 座標、y 座標とも 1/2 にする
関数 void half(POINT *p)
を作りなさい。
そして、以下の main 関数によりその関数をテストしなさい。
#include <stdio.h>
typedef struct point {
double x;
double y;
} POINT;
void half(POINT *p);
main(){
POINT p={6.0,8.0};
printf("最初の点は %f, %f です。",p.x,p.y);
half(&p);
printf("半分の位置は %f, %f です。",p.x,p.y);
}