%=====================================================================
% 秋田高専 2E 情報工学概論 テキスト
%　　テーマ　構造体
%    本テキストの内容
%        ・
%        ・
%        ・
%        ・
%　　　 　・
%
% last updated 2005.4.14
%    created by  Masashi Yamamoto
%     e-mail yamamoto@akita-nct.jp
%=====================================================================
\documentclass[10pt,a4paper]{jarticle}
\usepackage{html,graphicx,amsmath,amssymb,ascmac,float}
\oddsidemargin 0mm  %左の余白 25.4mm-0mm　奇数ページ
\evensidemargin 0mm %左の余白 25.4mm-0mm　偶数ページ
\textwidth 160mm
\newcommand{\command}[1]{「\texttt{#1}」}
\newcommand{\cl}[1]{\texttt{#1}}
\newcommand{\tw}[1]{\texttt{#1}}
%
\begin{document}
\title{構造体}
\author{山本昌志\thanks{独立行政法人　秋田工業高等専門学校　電気情報工学科}}
\date{2005年4月14日}
\maketitle
%
%
%=====================================================================
\section{本日の学習内容}
%=====================================================================
本日は、配列と構造体の違い示し、後者が便利なデータ構造であることを学習する。そ
して、それをC言語で実装する方法を学ぶ。これを学ぶことにより、分かりやすいプログ
ラムが書けるようになる。

構造体は、プログラマーがデータの内容を分かりやすくするための変数を定義するような
ものである。変数といっても、それはデータの集合体となっている。そのことを理解して、
それが便利だと分かって欲しい。
%
\newpage
%=====================================================================
\section{構造体とは}
%=====================================================================
以前示したように、プログラミングで使われるデータ構造は、表
\ref{table:kind_of_data_structure}のようなものがある。本日は、構造体を学習する。

構造体を学習するとほぼ基本データ構造の学習は終了する。問題向きデータ構造について
は、後期に学習することになる。

構造体を配列の違い、そして、構造体が便利な理由を、教科書に沿って説明する。
%
\begin{table}[hbtp]
 \begin{center}
  \caption{データ構造の種類}
  \label{table:kind_of_data_structure}
  \begin{tabular}{|l|l|l|l|l|}
   \hline
   データ構造 & 基本データ構造 & 基本データ型 & 単純型 & 整数型 \\
   \cline{5-5}
   &              &             &       & 実数型 \\
   \cline{5-5}
   &              &             &       & 文字型 \\
   \cline{5-5}
   &              &             &       & 論理型 \\
   \cline{5-5}
   &              &             &       & 数え上げ型 \\
   \cline{4-5}
   &              &             & \multicolumn{2}{l|}{ポインタ型} \\
   \cline{3-5}
   &              & 構造型       & \multicolumn{2}{l|}{配列型} \\
   \cline{4-5}
   &              &             & \multicolumn{2}{l|}{レコード型} \\
   \cline{3-5}
   &              & \multicolumn{3}{l|}{抽象データ型} \\
   \cline{2-5}
   & 問題向きデータ構造 & 線形リスト & \multicolumn{2}{l|}{単純リスト} \\
   \cline{4-5}
   &              &             & \multicolumn{2}{l|}{双リスト} \\
   \cline{4-5}
   &              &             & \multicolumn{2}{l|}{環状リスト} \\
   \cline{3-5}
   &              & 木          & 二分木 & 完全二分木 \\
   \cline{5-5}
   &              &             &       & 二分探索木 \\
   \cline{5-5}
   &              &             &       & バランス木 \\
   \cline{4-5}
   &              &             & \multicolumn{2}{l|}{多分木} \\
   \cline{4-5}
   &             &             & バランス木 & AVL木 \\
   \cline{5-5}
   &              &             &           & B木 \\
   \cline{3-5}
   &              & \multicolumn{3}{l|}{スタック} \\
   \cline{3-5}
   &              & \multicolumn{3}{l|}{キュー} \\
   \hline
  \end{tabular}
 \end{center} 
\end{table}
%
%
%
%=====================================================================
\section{構造体の文法}
%=====================================================================
教科書は分かり易く書かれているが、説明不足の所がある。そこで、退屈ではあるが細か
い説明をしておく。
%---------------------------------------------------------------------
\subsection{構造体型の定義}
%---------------------------------------------------------------------
%-------------------
\subsubsection{基礎}
%-------------------
構造体は、メンバーと呼ばれる変数の集合体の型である。プログラマーが新たに型を定義
するようなものである。定義の方法は、一般的には次のようになる。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct タグ名　{
	  型 メンバー1名;
	  型 メンバー2名;
	  型 メンバー3名;
	  ・
	  ・
	  ・
	  型 メンバーN名;
	} 変数リスト;
 \end{verbatim}
\end{quote}
%
予約語(キーワード)\tw{STRUCT}は、構造体を定義するとコンパイラーに伝える役目があ
る。タグ名と言うのは、新たに定義した構造体の名前である。型を定義するのであるから、
その型の名前が必要なのである。型は、メンバーの型を示す。これは、C言語で使うこと
ができる通常の型である。たとえば、\tw{int}, \tw{double}, \tw{char}等で、構造体も
メンバーの型として、使える。メンバー名は、構造体を構成する変数の名前で、そのデー
タにアクセスするために必要である。変数リストは、ここで定義された構造体を使う場合
の変数名である。

タグ名と変数リストのどちらか一方は省略可能である。タグ名を省略すると構造体の型名
が無くなるので、その内容がわかりにくくなり、通常は省略しない。一方、変数リストが
省略されることは、しばしば生じる。

それでは、例として学生の名前と成績、身長、体重を示した構造体を定義してみる。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei{
	  char name[80];
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	  double height;
	  double weight;
	} sato, tanaka, yamamoto;
 \end{verbatim}
\end{quote}
%
これで、\tw{gakusei}型の構造体変数の\tw{sato}と\tw{tanaka}、\tw{yamamoto}が使え
るようになる。さらに、\tw{watanabe}という変数を追加したい場合は、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei watanabe;
 \end{verbatim}
\end{quote}
%
とすればよい。

変数リストを省略すると、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei{
	  char name[80];
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	  double height;
	  double weight;
	};
 \end{verbatim}
\end{quote}
%
となる。こうすると、この\tw{gakusei}型の構造体変数を使うためには、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei sato, tanaka, yamamoto;
 \end{verbatim}
\end{quote}
%
のようにプログラム中で書く必要がある。
%

一方、タグ名を省略すると、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct {
	  char name[80];
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	  double height;
	  double weight;
	} sato, tanaka, yamamoto;;
 \end{verbatim}
\end{quote}
%
となる。この場合は、新たにこの型の構造体変数を追加することができないので、不便な
場合がある。変数の数があらかじめ分かっている場合に使われる。
%
%-------------------------
\subsubsection{変数を配列に}
%-------------------------
先の例だと、学生数が多くなると不便になる。多くのデータを扱う場合は配列が便利なの
は以前述べたとおりで、ここでもそれが使える。たとえば、クラス毎に
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei{
	  char name[80];
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	  double height;
	  double weight;
	} M2[50], E2[50], C2[50], B2[50];
 \end{verbatim}
\end{quote}
%
とする事ができる。

変数リストを省略して、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei{
	  char name[80];
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	  double height;
	  double weight;
	};
 \end{verbatim}
\end{quote}
%
と構造体を定義して、プログラム中で、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct gakusei M2[50], E2[50], C2[50], B2[50];
 \end{verbatim}
\end{quote}
%
と書き、変数を使うこともできる。
%
%--------------------------------
\subsubsection{メンバーを構造体型に}
%--------------------------------
先のデータを見ると、成績を表すメンバー(\tw{mathematics, english, japanese,
electrical\_eng, info\_eng})は似たようなデータで関連が強い。これは一つにまとめる
とデータの内容が分かり易くなり、プログラムの見通しが良くなる。そのためには、次に
示すように構造体のメンバーを使えば良い。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct seiseki{
	  int mathematics;
	  int english;
	  int japanese;
	  int electrical_eng;
	  int info_eng;
	};

	struct gakusei{
	  char name[80];
	  struct seiseki test;
	  double height;
	  double weight;
	};
 \end{verbatim}
\end{quote}
%
このように入れ子にすることを、構造体のネストと言う。ここでは2段のネストであるが、
3段でも4段でも可能である。
%---------------------------------------------------------------------
\subsection{構造体型のメンバーの参照}
%---------------------------------------------------------------------
構造体のメンバーの参照には、\tw{.}演算子 (ドット演算子)をつかう。次のようにする
のである。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
構造体変数.メンバー                           /* 通常 */
構造体変数.メンバー.メンバー                   /* メンバーが構造体 */
構造体変数.メンバー.メンバー.メンバー           /* メンバーのメンバーも構造体*/
構造体変数[配列の添え字].メンバー               /* 構造体が配列*/
構造体変数.メンバー[配列の添え字]               /* メンバーが配列*/
構造体変数[配列の添え字].メンバー[配列の添え字]   /*構造体もメンバーも配列*/
 \end{verbatim}
\end{quote}
%
ようするに、構造体といえども、ドット演算子を使う以外は通常の変数とほとんど同じで
ある。それでは、実際のプログラム例で、それを見てみよう。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	#include <stdio.h>
	#include <string.h>

	struct seiseki{
	  int mathematics;
	  int english;
	};

	struct gakusei{
	  char name[80];
	  struct seiseki test;
	  double height;
	};

	int main(){

	  struct gakusei e2[10];

	  strcpy(e2[0].name,"yamamoto");
	  e2[0].test.mathematics = 95;
	  e2[0].test.english = 65;
	  e2[0].height = 174.8;

	  printf("%s\n", e2[0].name);
	  printf("  Mathematics : %d\n", e2[0].test.mathematics);
	  printf("  English     : %d\n", e2[0].test.english);
	  printf("  Height      : %f [cm]\n", e2[0].height);

	  return 0;
	}
 \end{verbatim}
\end{quote}
%

構造体は通常の変数のように取り扱うことができるので、\tw{scanf}をつかって、キーボー
ドからデータを読み込む場合は、次のようにする。先ほどのプログラムで、キーボードか
ら入力された値をメンバーの\tw{mathematics}に格納するためには次のようにする。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	scanf("%d",&e2[0].test.mathematics);
 \end{verbatim}
\end{quote}
%
通常の変数同様、格納する変数(ここではメンバー)の頭に\tw{\&}をつけるだけである。
%
%---------------------------------------------------------------------
\subsection{構造体型を使うときの注意}
%---------------------------------------------------------------------
\begin{itemize}
 \item 構造体のメンバー名と通常の変数には同じ名前が使える。すなわち、以下は問題
       ない。
       %
       \begin{quote}
	\setlength{\baselineskip}{12pt}
	\begin{verbatim}	
	struct seisu{
	  int i;
	  int j;
	};

	struct seisu k,l;
	int i,j;		
	\end{verbatim}
       \end{quote}
\item 次のように構造体を宣言するときに、初期がができる。
       %
       \begin{quote}
	\setlength{\baselineskip}{12pt}
	\begin{verbatim}	
	struct seisu{
	  int i;
	  int j;
	};

	struct seisu k={1,2};
	struct seisu l[2]={{3,4},{5,6}};
	\end{verbatim}
       \end{quote}
	%
\item 同じ構造体であれば、代入演算子(\tw{=})を用いて、そのままコピーできる。いち
       いちメンバー毎、コピーする必要はない。
       %
       \begin{quote}
	\setlength{\baselineskip}{12pt}
	\begin{verbatim}	
	struct seisu{
	  int i;
	  int j;
	};

	struct seisu k, l={1,2};
	k=l;
	\end{verbatim}
       \end{quote}
	%
\item 構造体同士の比較は無意味であるし、できない。比較する場合は、メンバーを比較
       する。
\item 関数の引数に構造体を用いることは、問題なく可能である。ふつうの変数のように
       考えればよい。
\end{itemize}
%
%=====================================================================
\section{練習問題(プログラム作成)}
%=====================================================================
教科書の練習問題p.288のプログラムを作成せよ。どうしてもわからない場合
は、答えをみて、そのプログラムの内容を理解せよ。
%
%---------------------------------------------------------------------
\subsection{アンケート集計}
%---------------------------------------------------------------------
教科書の練習問題 Lesson 8-1のプログラムを作成せよ。
%
\begin{itembox}[l]{Lesson 8-1}
以下のような予想結果を10人分入力し、男女別の予想結果を「勝ち・引き分け・負け」に
 分けて集計し、表示するプログラムを構造体を利用して作成しなさい。
\end{itembox}
%
%---------------------------------------------------------------------
\subsection{-応用問題-データをまとめて管理する1}
%---------------------------------------------------------------------
教科書の練習問題 Lesson 8-2のプログラムを作成せよ。
%
\begin{itembox}[l]{Lesson 8-2}
音楽CD 10枚に入っている曲 (各CDには6曲) を入力し、テキストファイルに記録するプロ
グラムを作成しなさい。ただし、作成するテキストファイル(CDdata.txt)は次の通りとし
ます。
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	CD1 title:Zokkon C GENGO
	Artist: Hoge Maru
	song1: Ikeike hensuu
	song2: Hairetu BANZAI
	  ・
	  ・
	  ・
	song6: Saraba Kozoutai
	CD2 Title: Love Love C
	Artist: etc etc
 \end{verbatim}
\end{quote}
プログラム中のCDデータの取り扱いには、構造体を使うこと。
\end{itembox}
%
%
%---------------------------------------------------------------------
\subsection{-応用問題-データをまとめて管理する2}
%---------------------------------------------------------------------
教科書の練習問題 Lesson 8-3のプログラムを作成せよ。
%
\begin{itembox}[l]{Lesson 8-3}
 Lesson 8-2で作成したテキストファイルを読み込み、曲名を入力するとその曲が入って
 いるCDの名前と何番目かを表示してくれるプログラムを作成しなさい。
\end{itembox}
%
%=====================================================================
\section{レポート}
%=====================================================================
%---------------------------------------------------------------------
\subsection{内容}
%---------------------------------------------------------------------
練習問題のプログラムのうち、「アンケート集計」と「-応用問題-データをまとめて管理
する1」を完成させること。実行の確認ができたならば、それをプリントアウトして、レ
ポートとして提出する。

将来、情報処理関係の仕事に就きたいと思っている者は、頑張って、最後の「-応用問題-
データをまとめて管理する2」を完成させよ。最後の問題は、できた者のみレポートとし
て提出のこと。

自宅のプログラムを作っても良い。そして、実行の確認がとれたならば、それをプリント
アウトし、レポートとして提出しても良い。
%
%---------------------------------------------------------------------
\subsection{レポート提出要領}
%---------------------------------------------------------------------
提出方法は、次の通りとする。
% 
\begin{quote}
 \begin{tabular}{ll}
  期限 & 後日、指定する。 \\
  用紙 & A4 \\
  提出場所 & 山本研究室の入口のポスト \\
  表紙 & 表紙を1枚つけて、以下の項目を分かりやすく記述すること。\\
       & \qquad 授業科目名「情報工学」\\
       & \qquad 課題名「課題　構造体の練習」\\
       & \qquad 1E\quad 学籍番号\quad 氏名\\
       & \qquad 提出日\\
  内容 & ソースプログラム(プリントアウトのみ、手書きは不可)
 \end{tabular}
\end{quote}
%
%
%=====================================================================
\end{document}
