ページ 11

構造体の受け渡し

Posted: 2014年1月22日(水) 22:13
by khaki
構造体をアドレス渡しで関数に渡そうとしているのですが、
その際に、関数が複数あったり階段状になってたりして毎回引数として構造体のアドレスを渡してるのですが、
関数の数がおおくなるにつれ、どうしていいのか分からなくなってしましました。

特に階段状?(void a(){引数};のなかにvoid d(){引数}; void c(){},のような場合)おいて
cでのみ構造体にしたい場合は、引数としてa,b,cと順番に渡すのかexturn(未学習)ようなものでどこからでもアクセスできるようにする、状況によって使い分けるなど、どのような方法がプログラムとして効率がいいのでしょうか?

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 22:16
by khaki
訂正:下2行目
cでのみ構造体にアクセスしたい場合でした

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 22:31
by softya(ソフト屋)
externも限定的には使っても良いと思いますが参照のみに限ったほうが安全です。
更新が伴うと関数ネストの深くに持ち込むのは場合によっては仕方ないことかも知れません。

ところでa(引数)→b(引数)→c(引数)と言うネストなのでしょうか?
設計次第で変わる面も多いので、ほんとうに必要なネストか?って事も見なおしてみたほうが良いでしょう。

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 22:51
by khaki
おそらくネストだと思います。
引数や構造体の事ばかり考えて、設計を変更することを考えてませんでした。

それでは設計する際、ネスト構造にする場合は更新処理をする部分をできる限り浅い部分で行い、深い位置では参照や計算などを行うような設計をすればいいのでしょうか?

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 23:02
by softya(ソフト屋)
externも構造体の持ち回りも何処で更新したか分かりづらく成るという根本的問題を抱えていますので無いに越したことがないのですが、プログラム構造として出来るだけ分かりやすくしてやればバグの可能性は減ります。それには更新タイミングをシンプルにすることです。
そのためには関数名で更新を明確する事や、できるだけ浅いネスト階層の置いたほうが分かりやすくなります。

何でもかんでも構造体に置いて使わないものをあちこちの関数に引き回しているのならexternのグローバル変数と何ら変わりありません。
構造体を分割する事や最低限の引数のために別構造体にコピーするなども時には必要です。

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 23:19
by khaki
今まで設計についてあんまり考えたことがなかったので、とてもためになりました。
もう一度、設計を見直してみたいと思います。 ありがとうございました。

Re: 構造体の受け渡し

Posted: 2014年1月22日(水) 23:37
by softya(ソフト屋)
khaki さんが書きました:今まで設計についてあんまり考えたことがなかったので、とてもためになりました。
もう一度、設計を見直してみたいと思います。 ありがとうございました。
補足しておきますと、その場での修正が楽、後々でも追加・修正が楽、デバッグ時の問題点の発見が楽などを考慮していく必要があります。
バグの多くは更新と参照がちぐはぐに成ることで引き起こされます(それ以外も当然ありますけどね)。
どのタイミングで更新しているのか簡単に調べられないプログラムはバグの温床となる可能性が大きいです。

2重に更新したり、更新前に参照したりすると思うようには動きませんよね。そういうバグを減らすための分かりやすい合言葉が「グローバル変数(extern)を無くそう」です。
ただ、表面的な意味だけなく何の為にやるかを常に考えていないと構造体の引数でもグローバル変数と同じ問題を引き起こします。