博士

構造体のコピー方法についていくつか紹介するぞい。

関数への構造体の渡し方

  1. 値渡し

    構造体を渡し、値が関数の構造体に複写される。

  2. 構造体を渡し、値が関数の構造体に複写される

    構造体のアドレスを渡し、ポインタで受け取る。

  3. 構造体を返す

    構造体全体を戻り値にする。

構造体の値渡し

博士「ここをチェックじゃ」

まず、値渡しをみてみようかの。

呼 ぶ 側
kansu(構造体名)
呼ばれる側
kansu(struct タグ名 構造体変数名)
struct タグ名は引数の型を表している。

値渡しのプログラム

#include <stdio.h>
struct meibo {
   int cobol; int casl; int goukei;
};

void kansu(struct meibo data);

main()
{
   struct meibo data={100,99,0};
   kansu (data);
   printf("main :goukei=%d\n",data.goukei);
}

void kansu(struct meibo data) {
   data.goukei=data.cobol+data.casl;
   printf("kansu:goukei=%d\n",data.goukei);
}

実行結果

kansu:goukei=199
main :goukei=0

値の渡り方

main側
kansu(data);

data.cobol[ 100 ]
data.casl [ 99 ]
data.goukei[ 0 ]
コピーされる


⇒⇒⇒
⇒⇒⇒
⇒⇒⇒
kansu側
kansu(struct meibo data)

data.cobol[ 100 ]
data.casl [ 99 ]
data.goukei[ 0 ]

博士

mainに戻ってもgoukeiは「0」のままなんじゃ。
なんでか分かるかの?


ぷうさん

値渡しだからでしよ?

構造体のアドレス渡しじゃぞ

博士「ここをチェックじゃ」

お次は、mainに値が返るアドレス渡しじゃぞ。

呼 ぶ 側
kansu(&構造体名)
またはkansu(ポインタ)
呼ばれる側
kansu(struct タグ名 *ポインタ)
struct タグ名は構造体のポインタであることを表している。

構造体の先頭アドレスがポインタに渡る。

構造体メンパーは「(*ポインタ),メンパー名」で指定する。

メンパ演算子「->」

構造体への「ポインタ->メンパー名」

構造体へのポインタを利用してメンバーを指定する場合には、一般的に「(*ポインタ),メンパー名」よりも、「ポインタ->メンパー名」を用いる。

  1. メンバー演算子「. 」を使った例
    (*data).goukei
  2. メンバー演算子「->」を使った例
    data->goukei

アドレス渡しのプログラム

#include <stdio.h>
struct meibo {
   int cobol; int casl; int goukei;
};

void kansu(struct meibo *data);

main()
{
   struct meibo data={100,99,0};
   kansu (&data);
   printf("main :goukei=%d\n",data.goukei);
}

//↓ここ↓の関数部分は変更可能(メンバー演算子)
void kansu(struct meibo *data) {
   (*data).goukei=(*data).cobol+(*data).casl;
   printf("kansu:goukei=%d\n",data.goukei);
}






関数部分のメンバー演算子を「->」に変更

//↓ここ↓の関数部分は変更可能(メンバー演算子)
void kansu(struct meibo *data) {
   data->goukei=data->cobol+data->casl;
   printf("kansu:goukei=%d\n",data->goukei);
}

実行結果

kansu:goukei=199
main :goukei=199

博士「(^^♪」

どうじゃ!


ぷうさん「OK」

あ、値渡しだとmain側のgoukeiが0のままだったのに、今度のアドレス渡しだとちゃんと合計が反映されている!

構造体全体を返す関数

struct タグ名 関数名( 引数) {
関数の処理
return(構造体);
}
struct タグ名は構造体を返す事を意味する。

  1. 整数型の関数
    int kansu(・・・・)
  2. 構造体型の関数
    struct meibo kansu(・・・・)

構造体型の関数のプログラム

include <stdio.h>

struct meibo {
   int cobol; int casl; int goukei;
};

struct meibo kansu(struct meibo data);

main()
{
   struct meibo data={100,99,0};
   struct meibo test={0,9,0};

   printf("1-a:%d %d %d\n",test.cobol,test.casl,test.goukei);
   test=kansu(data);
   printf("1-b:%d %d %d\n",test.cobol,test.casl,test.goukei);

   printf("2-a:%d %d %d\n",test.cobol,test.casl,test.goukei);
   test=kansu(data);
   printf("2-b:%d %d %d\n",test.cobol,test.casl,test.goukei);
}

struct meibo kansu(struct meibo data) {
   data.goukei=data.cobol+data.casl;
   return(data);
}

実行結果

1-a:0 0 0
1-b:100 99 199
2-a:100 99 0
2-b:100 99 199

ぷうさん「×」

ブーブーブーッ!オーバーフロー始めました。
速やかにデータ人力を中止し、電源をお切り下さい。
さもないと、既に書き込まれたデー夕をも一緒に破壊されます。
CAUIION! 速やかに・・・・・


博士「?」

何をまたおかしな事を言っとるんじゃ?


ぷうさん「×」

ブーッブーッブーッ!!
危険です!危険です!


困った顔の博士

しかたないのぉ・・・今日はまとめて終わりにするぞ。


ぷうさん「×」

ブーッブーッブーッ!!
危険です!データ人力が拒否されました。
CPU破壊を避ける為、プロテクトモードに入ります。
一切のアクセスは拒否されます。
オートデリ一卜機能稼働・・・・・


博士

お、おい・・・ぶうさんっ!


ぷうさん

・・・・・・


博士「ここをチェックじゃ」

仕方ない、一応次の記事(その三)にまとめておくんでの。
正常な状態に戻ったら読んでおくんじゃぞ。

その三 構造体のまとめへ

六日目 構造体について 目次

五日目へ

ぷうさんの七日間戦争 六日目

七日目へ