みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語の構造体

組込み系でマイコンにソフトをプログラミングの仕事をしています。
C言語は初心者です。

http://www9.plala.or.jp/sgwr-t/c/sec15.html
のページの冒頭に、
「構造体は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。」と書かれています。
1つのデータ型として扱うとどのようなメリットがあるのでしょうか?
例えば、
struct seiseki seito1;
のように対象が1つ(seito1)なら
intseito1_no;
char seito1_name[20];
doubleseito1_average;
と変数を確保すれば済むのに、
何故、構造体で宣言するのでしょうか?
例えば、
struct seiseki seito2[20];
のように、似たものが複数ある場合は(seito2が20人分なるなら、)
構造体で宣言する意味があるとはなんとなくわかります。

後ページの
http://www9.plala.or.jp/sgwr-t/c/sec15-4.html
では、関数でのやり取りが書かれています。
関数で引数や返値で扱うときに構造体にしておいた方が良いからでしょうか?
構造体のメリットというのが今一わかりません。
対象が1つでも構造体で書いた方がいろんな意味で良いのでしょうか?

如何せん、初心者なので質問がうまく書けませんがご了承ください。
※上から目線的な回答はご遠慮願います。

投稿日時 - 2017-08-19 16:16:23

QNo.9364822

困ってます

質問者が選んだベストアンサー

No3です。

>仮に関数での引数で使わない場合でも構造体で書いた方が良いということでしょうか?

そうですね。ある処理ブロックの中でしか使わない使い捨て的なデータならどうでもいいのですが、プログラムの動作期間中に保持され続けるデータであるとか、動作に影響を与えるようなある程度重要なデータに関しては、そのデータの内容に応じてまとめておいた方がいいです。理由はNo3にも書きましたが、あとから見た人がプログラムの意図を理解しやすくなる可能性があるからです。
ですが、どのデータが重要なデータだと判断するか、またどのデータをまとめて構造体化するか、といった点でプログラム作成者のセンスがモロに出ます。
質問者さんの例で言うと、生徒番号、名前、成績データを構造体として定義していると、あとから見た人は「ああ、生徒ごとの成績情報を管理、処理しようとしてるんだな」と想像がつきますが、ここにプログラム動作に必要だからと言ってプログラムの起動時間を管理する変数とか画面のボタン状態を管理する変数とかを同じ構造体のメンバに追加したらワケ分からなくなります。こういった、どのデータをどうまとめるかも設計力ですね。
もうちょっと言いますと、生徒ごとの成績情報みたいなそのプログラムで扱う大事なデータについては、実領域の確保、解放、内容の初期化、データの追加、更新、削除などの各処理をそれぞれ専用の下請け関数でやらせるようなプログラム構成にするのがセオリーです。そうするとおや関数から下請け関数を呼び出す時に、引数で渡すような形になるはずです。なぜこれがセオリーかは説明するのが大変ですが、「構造化プログラム」を勉強し、また一つのプログラムを複数人で開発する状況になると身についてくるはずです。

投稿日時 - 2017-08-20 22:15:27

お礼

丁寧な回答ありがとうございます。
ソフトに対する気持ちが少し楽になりました。
構造化プログラム 調べてみます。

投稿日時 - 2017-08-22 21:45:08

ANo.5

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.4

>>回答者様は、どのようにして理解や習得されたのでしょうか?
教えてください。宜しくお願いします。

私がC言語を学んだ頃は、世の中は「猫も杓子もC言語」って雰囲気がありました。
ですので、書店には、C言語専門の月刊誌が並んでいたり、C言語の専門書も沢山並んでいました。
でも、多くの書籍は入門レベルであり、それらから実務レベルのC言語を学ぶのは困難だったように記憶しています。

とはいえ、C言語の中級以上の書籍が出版されていたのも確かです。
ある書籍では、C言語がどのようにマシン語に翻訳されるかについて、多くのページを使って、丁寧に解説してありました。
別の書籍では、1冊丸ごと「C言語を使って、MS-DOSで動作するC-Shellを作ろう」的な書籍がありました。
それを参考に、別のOSに、その便利なC-Shellを移植する作業をしました。

また、そのOSには、使いやすいデータベースが存在しなかったので、米国からデータベース的に使えるC言語のソースを購入して移植作業をしました。
購入したソースコードは膨大で、それまで見たこともないような命令の使い方がいくつもあり、しかも日本語対応も必要だったため、かなり移植には時間がかかりました。
そのように実務で使うようなC言語で書かれたソフトウエアの移植作業を通じて、C言語の理解をすることができたと思っています。

なお、絶版みたいですが「エキスパートCプログラミング 知られざるCの深層」とか、「BINARY HACKS ハッカー秘伝のテクニック100選」の書籍はC言語を深く理解するのに役にたつと思います。

投稿日時 - 2017-08-20 17:19:45

お礼

回答ありがとうございます。
絶版ですか、ちょっと調べてみます。

投稿日時 - 2017-08-22 21:49:56

ANo.3

プログラムが複雑になってくるとたくさんのデータを扱うことになりますが、いろんなデータの中からどのデータをひとかたまりとして扱おうとしているのかが分かりやすくなります。たとえば質問者さんの例だと生徒番号、名前、平均値をそれぞれ扱っていますが、これらを構造体として定義することで、後からプログラムを見た人が、そのプログラムではどのデータを関連したデータとして扱おうとしているのかの意図を理解しやすくなります。
また、質問者さんが挙げているURLにあるように、こういったデータは関数間の引数として渡すことが多いのですが、関数呼び出し時のパラメタに生徒番号、名前、平均値の3つを渡すより、構造体へのポインタを渡した方が記載が簡単です。
さらにはたとえば5教科の得点すべてを管理するような改造が発生体場合はどうでしょう?もし構造体化していない場合は、3つのパラメタを渡していた関数間の受け渡しの記載をすべて修正する必要がありますが、構造体化していた場合は構造体の定義を修正するだけで関数間のインタフェースの記載は修正しなくてもビルドできます。そして構造体のメンバ変数を追加や変更する場合、それがどの関数に影響するのかを調べることも簡単になります(構造体の定義名で検索すると影響範囲が分かる)。こういった点から保守性も向上します。

なお、C言語では扱うデータをひとかたまりにするのが構造体ですが、C++やJavaなどオブジェクト指向言語は、扱うデータとそのデータを処理する関数をひとかたまりにする、という考え方します(もっといろんな概念を含んでいますが、一番の基本はここ)。
なので、構造体を使いこなすことがオブジェクト指向言語の考え方を知る第一歩である、とも言えます。

投稿日時 - 2017-08-19 21:11:49

補足

ご回答ありがとうございます。
仮に関数での引数で使わない場合でも構造体で書いた方が良いということでしょうか?
ひょっとしたら、後々引数で使うかもしれないので構造体で書いておくということでしょうか?
よろしくお願いします。

投稿日時 - 2017-08-20 21:21:06

ANo.2

用途の参照ページの通りです。宣言が冗長になるのが防げ、引数の記述もシンプルになるので間違いも防げます。何を扱うかが明瞭になるので、見た目がキレイですよね。(笑)

投稿日時 - 2017-08-19 17:17:47

ANo.1

>>構造体は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。

このとおりのメリットです。
例えば、1つのデータとしてAさん1人の情報を確保する場合、住所、氏名、年齢、電話番号、メールアドレス・・・と沢山の情報が必要です。
もし、健康診断の情報まで入れたら、100項目を超えるかもしれません。
これを構造体として1つにまとめておけば、関数とのやりとりが1つの引数で済むため、楽になります。

ただ、このあたりは、入門レベルのC言語では、あまり記述がされてないことも多いので、C言語の初心者にはわかりにくい部分かもしれませんね。

投稿日時 - 2017-08-19 17:09:21

補足

私は、ソフトのプログラミングは経験がありますがC言語が初心者です。
「学校の勉強で言えば、教科書は理解できますが、その次の応用問題やテストになると点が取れない」そんな局面に立たされています。
「入門レベルでは記述されていない」ということは、
回答者様は、どのようにして理解や習得されたのでしょうか?
教えてください。宜しくお願いします。

投稿日時 - 2017-08-20 15:01:59

あなたにオススメの質問