構造体(ポインタ変数)
今回は、構造体のポインタ変数について軽く触れてみます。
さて、昔のC言語の規約では(K&Rなどでは)、構造体について以下のような制約がありました。
(1) 構造体(まるごと)を直接関数に渡したり、返したりできない。
(2) 構造体をまるごと(全メンバーのデータ)を、一度に同じ型の構造体に代入することはできない。
すなわちpersonal型の構造体変数 a,b
が以下のようにある時
struct personal {
char *name;
char *adress;
char *tel;
} a,b;
構造体(まるごと)の代入 a = b;
はできないということです。
(古いCの規約では、メンバー単位でのデータの代入
a.name = b.name;
しかできないことになっています。)
このような場合には、構造体のポインタを使って関数との受け渡しや、代入を行う必要がでてきます。
もっとも、最近の多くのC言語ではその制約がなくなっていますが。
T 構造体のポインタ変数の受け渡し
| #include <stdio.h> struct personal { char *name; char *adress; char *tel; } main(){ struct personal *ps, ps_data[2]; /* (1) */ int i; /* 下の ps=ps_data; がないと、コンパイル時に「PSの値が未定義」というエラーになる*/ ps=ps_data; /* (2) */ for(i=0;i<2;i++,ps++){ /* (3) */ printf("name? -"); gets(ps->name); printf("adress? -"); gets(ps->adress); printf("tel? -"); gets(ps->tel); printf("\n"); } ps=ps_data; /* (4) */ for(i=0;i<2;i++){ printf("%s : %s : %s\n",(*(ps+i)).name,(*(ps+i)).adress,(*(ps+i)).tel); } ps=ps_data; for(i=0;i<2;i++){ printf("%s : %s : %s\n",(ps+i)->name,(ps+i)->adress,(ps+i)->tel); } ps=ps_data; for(i=0;i<2;i++,ps++){ printf("%s : %s : %s\n",ps->name,ps->adress,ps->tel); }} |
| C:\C>struct name? -田中 adress? -東京都世田谷区 tel? -999-666-333 name? -Ron Bon adress? -NY, US tel? -777-999-999 田中 : 東京都世田谷区 : 999-666-333 Ron Bon : NY, US : 777-999-999 田中 : 東京都世田谷区 : 999-666-333 Ron Bon : NY, US : 777-999-999 田中 : 東京都世田谷区 : 999-666-333 Ron Bon : NY, US : 777-999-999 C:\C> |
U 構造体を関数で受け渡し
#include <stdio.h>
void input(struct personal *);
void display(struct personal *);
struct personal {
char *name;
char *adress;
char *tel;
}
main(){
struct personal ps_data[2];
input(ps_data);
display(ps_data);
}
void input(ps)
struct personal *ps;
{int i;
for(i=0;i<2;i++,ps++){
printf("name? -"); gets(ps->name);
printf("adress? -"); gets(ps->adress);
printf("tel? -"); gets(ps->tel); printf("\n");
}}
void display(ps)
struct personal *ps;
{int i;
for(i=0;i<2;i++,ps++){
printf("%s : %s : %s\n",ps->name,ps->adress,ps->tel);
}}
|
データの入力、出力用の関数 input, display
を用意し、main
でコールするという単純なプログラムです。
input, display では構造体配列 ps_data[ ]の先頭アドレス(ポインタ)
である ps_data を引数として関数
に渡します。それぞれの関数側では、構造体のポインタ変数
*ps で構造体のデータを受け取っています。
| C:\C>struct2 name? -kasai tsuyoshi adress? -setagaya,Tokyo tel? -000-888-999 name? -bon adress? -NY,US tel? -888-333-222 kasai tsuyoshi : setagaya,Tokyo : 000-888-999 bon : NY,US : 888-333-222 |
構造体のポインタ変数は、若干わかりにくいところがあると思いますが、自分でプログラムしてみると
徐々に理解できるようになるでしょう。