%=====================================================================
% 秋田高専 2E 情報工学概論
% 
% last updated 2005.8.22
%    created by  Masashi Yamamoto
%     e-mail yamamoto@akita-nct.jp
%=====================================================================
\documentclass[10pt,a4paper]{jarticle}
\usepackage{graphicx,amsmath,amssymb,ascmac,float,misc,multicol}
\usepackage{html, listings, jlisting}
\oddsidemargin 0mm  %左の余白 25.4mm-0mm　奇数ページ
\evensidemargin 0mm %左の余白 25.4mm-0mm　偶数ページ
\textwidth 160mm
%
\newcommand{\command}[1]{「\texttt{#1}」}
\newcommand{\tw}[1]{\texttt{#1}}
\renewcommand{\lstlistingname}{リスト}
\lstset{language=C,%
        basicstyle=\footnotesize,%
        commentstyle=\textit,%
        classoffset=1,%
        keywordstyle=\bfseries,%
	frame=tRBl,framesep=5pt,%
	showstringspaces=false,%
        numbers=left,stepnumber=1,numberstyle=\footnotesize%
	}%
%
\newcounter{toi_num}
\newcommand{\toi}{\textbf{\texttt [問\arabic{toi_num}]}
   \addtocounter{toi_num}{1}}
\newcommand{\qbox}[1]{
    {\fboxsep=2pt\fboxrule=0.4pt\fbox{\hspace{3mm}{#1}\hspace{3mm}}}
}
%
\begin{htmlonly}
\usepackage{verbatimfiles}
 \providecommand{\lstinputlisting}[2][]{\verbatimlisting{#2}}
\end{htmlonly}
%
\begin{document}
\title{補講(中間試験不合格者向け)}
\date{2005年8月23日}
\author{山本昌志\thanks{国立秋田工業高等専門学校　電気情報工学科}}
\maketitle
%
本テキストは、中間テストでの不合格者に向けての補講に使用する。補講対象者は、この
テキストに書いてある内容を理解し、前回の中間試験の問題が全て解けるようになって、
再試験に臨むこと。
%=====================================================================
\section{いろいろなデータ構造}
%=====================================================================
これまで3つのデータ構造を学習した。単純型と配列、構造体である。それぞれの概略は
以下の通り。
%---------------------------------------------------------------------
\subsection{単純型}
%---------------------------------------------------------------------
単純型の変数は、次のように変数に一つの数値\footnote{一つの文字のみ代入可能なもの
は文字型の変数である。文字も整数として扱えるので、この範疇と考える。}しか代入で
きないものを言う。これを使う場合、以下のように宣言する。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	char c, h, moji;
	int i, j, seisu;
	double x, y, jisu;
 \end{verbatim}
\end{quote}
%
これのイメージは、図\ref{fig:image_variable}に示しているとおりで、変数とは数値を
入れる箱のようなものである。整数型と倍精度実数型の変数は、数学の変数とよく似てい
る。
%
\begin{figure}[hbpt]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]
  {figure/image_variable.eps}
  \caption{単純型のイメージ。変数とはデータを入れる箱のようなもの。}
  \label{fig:image_variable}
 \end{center}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{配列}
%---------------------------------------------------------------------
順序づけられた同じ型のデータが複数ある場合、配列の出番となる。添え字(これが順序を表
す)により、それらにアクセスできるので、データの操作が簡単にできる。
配列を使う場合、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	int i[10], j[100][100];
 \end{verbatim}
\end{quote}
%
のように宣言を行う。そうすると必要なメモリー領域が確保され、配列が使えるようにな
る。この配列のデータにアクセスするためには、配列名と添え字を指定する。次のように
である。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	i[3]=5;
	c=i[3];
 \end{verbatim}
\end{quote}
%
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]
  {figure/image_array.eps}
  \caption{配列のイメージ。データを入れる箱がいっぱいある。ただし箱の大きさは全
  て同じ。}
  \label{fig:image_variable}
 \end{center}
\end{figure}
%
%
%---------------------------------------------------------------------
\subsection{構造体}
%---------------------------------------------------------------------
%---------------------------
\subsubsection{構造体の概要}
%---------------------------
配列は同じ型のデータの集まりであったが、構造体は異なる型のデータの集まりである
\footnote{同じ型でも良い}。この構造体を使う場合、
%
\begin{enumerate}
 \item 構造体のメンバーを規定する。これにより構造体を定義する。
 \item 構造体変数の宣言。これによりメモリーが確保される。
\end{enumerate}
%
という手順が必要である。このようにして、構造体を定義し、メモリーを確保した後、そ
れを使うことができる。今までは、データの型の内容があらかじめ決まっていたので、最
初の手順は不要であった。一方、構造体のメンバー、すなわちデータの型はプログラマーが
決めなくてはならないので、最初の手順が必要となる。

最初のメンバーの規定は、つぎのように行う。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct seito{
	  char name[128];
	  int kokugo;
	  int sansu;
	};
 \end{verbatim}
\end{quote}
%
これでは、メモリーがまだ確保されていないことに注意が必要である。これは、プログラ
マーが新たに変数を定義したのと同じである。

そして、この構造体を実際に使う場合には、次のようにしてメモリーを確保する。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct seito yamamoto, ninensei[50];
 \end{verbatim}
\end{quote}
%
そうすると構造体変数が使用可能となる。

メモリーに確保された構造体のデータにアクセスするためには、ドット(\tw{.})演算子を
使うことになる。次のようにである。
%
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	yamamoto.sansu = 63;
	ninensei[5].kokugo=76;
	tensu = ninensei[6].sansu;
 \end{verbatim}
\end{quote}
%

%-----------------------------
\subsubsection{構造体のイメージ}
%-----------------------------
構造体を図に示すと図\ref{fig:image_structure}の用になる。この場合構造体は
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct kouzoutai{
	  char name[8];
	  int seisu;
	  double jisu;
	};
 \end{verbatim}
\end{quote}
%
の用に定義し、
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct kouzoutai a, b[10];
 \end{verbatim}
\end{quote}
%
のように構造体変数を用意する。
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]
  {figure/image_structure.eps}
  \caption{構造体のイメージ。データを入れるいろいろな大きさの箱がある。}
  \label{fig:image_structure}
 \end{center}
\end{figure}
%
%
%---------------------------
\subsubsection{構造体型の定義}
%---------------------------
構造体は、メンバーと呼ばれる変数の集合体の型である。プログラマーが新たに型を定義
するようなものである。定義の方法は、一般的には次のようになる。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	struct タグ名　{
	  型 メンバー1名;
	  型 メンバー2名;
	  型 メンバー3名;
	  ・
	  ・
	  ・
	  型 メンバーN名;
	} 変数リスト;
 \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;
	} 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}
%
とすればよい。
%
%-------------------------------------
\subsubsection{構造体型のメンバーの参照}
%-------------------------------------
構造体のメンバーの参照には、\tw{.}演算子 (ドット演算子)をつかう。次のようにする
のである。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
構造体変数.メンバー                           /* 通常 */
構造体変数.メンバー.メンバー                   /* メンバーが構造体 */
構造体変数.メンバー.メンバー.メンバー           /* メンバーのメンバーも構造体*/
構造体変数[配列の添え字].メンバー               /* 構造体が配列*/
構造体変数.メンバー[配列の添え字]               /* メンバーが配列*/
構造体変数[配列の添え字].メンバー[配列の添え字]   /*構造体もメンバーも配列*/
 \end{verbatim}
\end{quote}
%
%-------------------------
\subsubsection{プログラム例}
%-------------------------
構造体を用いたプログラム例としてリスト\ref{prog:struct}を示す。この内容をよく理
解する必要がある。
%
\lstinputlisting[caption=構造体を使ったプログラム例,label=prog:struct]
{program/struct.c}
%
%
\fbox{実行結果}
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
yamamoto
  Mathematics : 95
  English     : 65
  Height      : 174.800000 [cm]
 \end{verbatim}
\end{quote}
%
\newpage
%=====================================================================
\section{2進数と16進数}
%=====================================================================
C言語の特徴であるポインターを学習するためには、2進数や16進数を理解する必要がある。
そのために、10進数とそれらの関係について学習した。以下、その内容をまとめる。
\begin{itemize}
 \item{いろいろな数の表記方法がある。N進数の場合、次のようにN個の
      底で数を表現する。\vspace{3mm}\\
      \begin{tabular}{rl}
       2進数  & 0,\,1\\
       10進数 & 0,\,1,\,2,\,3,\,4,\,5,\,6,\,7,\,8,\,9 \\
       16進数 & 0,\,1,\,2,\,3,\,4,\,5,\,6,\,7,\,8,\,9,\,A,\,B,\,C,\,D,\,E,\,F \\
      \end{tabular}\vspace{3mm}
      }
      %
 \item{桁上がりは、2進数の場合1の次で10に、10進数の場合9の次で10に、16
      進数の場合Fの次で10になる。}
      %
 \item{我々が通常用いている数の表現の意味は、次の通りである。数字の並ぶ
      順序が重要で、これを「位取り記数法」と言う。}
      \begin{align*}
       (1905)_{10}=(1\times 10^3+9\times 10^2+0\times 10^1+5\times 10^0)_{10}
      \end{align*}
      %
 \item{基数の変換(2→10進数)。通常の位取り記数法が理解できれば、簡単である。
      \begin{align*}
       (1101)_2
       &=(1\times10^{11}+1\times 10^{10}+0\times 10^{1}+1\times 10^{0})_2\\
       &=(1\times 2^3+1\times 2^2+0\times 2^1+1\times 2^0)_{10}
       \qquad\leftarrow\text{普通はここから計算}\\
       &=(8+4+0+1)_{10}
       \qquad\leftarrow\text{ここから計算しても良い}\\
       &=(13)_{10}
      \end{align*}
      }
      %
 \item{2進数の各桁の10進数の値(重み)を覚えておくと便利である。
      \begin{align*}
       1,\,2,\,4,\,8,\,16,\,32,\,64,\,128,\,256,\,512,\,1024,\,2048,\,4096
      \end{align*}
      }
      %
 \item{基数の変換(10$\rightarrow$2進数)。2で割った余りを並べればよい。変換方法の例を、
      以下に示す。\\
      $(19)_{10}=(10011)_2,\quad(2003)_{10}=(11111010011)_2$ である。
      %
      \begin{figure}[H]
       \begin{center}
	\includegraphics[keepaspectratio, scale=0.7]
	{figure/decimal_to_binary.eps}
	\caption{10進数から2進数への変換方法。}
	\label{fig:decimal_to_binary}
       \end{center}
      \end{figure}
      %
      }
      %
 \item{基数の変換(16$\rightarrow$10進数)。これも、2進数と同じ。
      \begin{align*}
       (376)_{16}
       &=(3\times 10^2+7\times 10^1+6\times 10^0)_{16}\\
       &=(3\times 16^2+7\times 16^1+6\times 16^0)_{10}\\
       &=(3\times 256+7\times 16+6\times 1)_{10}\\
       &=(886)_{10}
      \end{align*}
      }
 \item{基数の変換(10$\rightarrow$16進数)。16で割って、その余りが各桁になる。
      %
      \begin{figure}[H]
       \begin{center}
	\includegraphics[keepaspectratio, scale=1.0]
	{figure/decimal_to_hex.eps}
	\caption{10進数から16進数への変換方法。}
	\label{fig:binary_to_hex}
       \end{center}
      \end{figure}
      %
      }
 \item{基数の変換(2$\leftrightarrow$16進数)。2進数の4桁が、16進数の1桁に等しい
      ことを利用する。
      %
      \begin{figure}[H]
       \begin{center}
	\includegraphics[keepaspectratio, scale=1.0]
	{figure/binary_hex.eps}
	\caption{2進数と16進数の相互変換}
	\label{fig:binary__hex}
       \end{center}
      \end{figure}
      %
      }
 \item{桁数が合わない場合は、先頭に必要なだけゼロを書き足して考える。
      例えば、$(101100)_2 =(00101100)_2=(2\texttt{C})_{16}$ となる。}

\end{itemize}
%
\newpage
%=====================================================================
\section{ポインター}
%=====================================================================
%---------------------------------------------------------------------
\subsection{コンピューターの構造}
%---------------------------------------------------------------------
ポインターは、メモリーと密接に関わっている。ポインターを学習する前に、簡単にコン
ピューターの構造を学習した。その内容は、以下の通り。
\begin{itemize}
 \item 図\ref{fig:comp_5_equipments}がコンピューターの基本構成である。
 \item \textgt{制御装置}と\textgt{演算装置}、\textgt{記憶装置}、\textgt{入力装置}、
       \textgt{出力装置}をコンピューターの五大装置と呼び、それぞれには以下の働きがある。
%
 \begin{list}{}{\leftmargin=7zw \rightmargin=0zw \labelwidth=6zw}
  \item[\textgt{制御装置}]主記憶装置(メインメモリー)に格納されているプログラムを
			  受け取り、各装置に指令を出す。
  \item[\textgt{演算装置}]主記憶装置の中にあるデータを受け取り、制御装置の指令に
			  従い、それを処理する。
  \item[\textgt{記憶装置}]主記憶装置と補助記憶装置がある。
  \begin{list}{}{\leftmargin=7zw \rightmargin=0zw \labelwidth=6zw}
   \item[\textgt{主記憶装置}]命令とデータからなるプログラムを格納する。
   \item[\textgt{補助記憶装置}]大容量、あるいは半永久的に残したいデータを補助記憶
			    装置に格納する。
  \end{list}
  \item[\textgt{入力装置}]コンピューターの外部からデータを取り込む装置である。
  \item[\textgt{出力装置}]主記憶装置に格納されているデータをコンピューター外部に
			  出力する装置である。
 \end{list}
%
 \item 制御装置と演算装置をまとめて中央制御装置(CPU:Central Processing Unit)ある
       いは、 MPU(Micro Processing Unit) と言う。
\end{itemize}
%

%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]
  {figure/comp_5_equipments.eps}
  \caption{コンピューターの基本構成}
  \label{fig:comp_5_equipments}
 \end{center}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{メモリーとデータ}
%---------------------------------------------------------------------
\begin{itemize}
 \item 2進数の1桁が1ビットである。
 \item 諸君が使っているパソコンのアドレスは32ビットで表現されている。これは16進
       数では8桁である。
 \item 一つのアドレスに8ビット(1バイト)記憶できる。これは、16進数2桁で表現できる。
 \item 8ビットを1バイトと言う。
 \item 諸君が使っているコンパイラーでは、変数は表\ref{table:var_type_byte}に示し
       ているバイト数で表現されている。
%
\begin{table}[H]
 \caption{変数の型とバイト数}
 \label{table:var_type_byte}
 \begin{center}
  \begin{tabular}{llrr}
   \hline
   \multicolumn{1}{c}{型名} &
   \multicolumn{1}{c}{データ型} &
   \multicolumn{1}{c}{バイト数} &
   \multicolumn{1}{c}{ビット数} 
   \\ \hline \hline
   文字型 & char & 1 & 8 \\
   整数型 & int & 4 & 32 \\
   倍精度実数 & double & 8 & 64 \\
   \hline
  \end{tabular}
 \end{center}
\end{table}
%
  \item プログラムは命令とデータから構成され、いずれもメモリーの中に格納される。
  \item プログラムの関数(これが命令)が格納されるアドレスは、関数名で参照できる。
  \item データが格納されるアドレスは、データ名の前に\tw{\&}を付けることで参照で
	きる。\tw{\&} はアドレス演算子である。
  \item アドレスの表示には変換指定子 \tw{\%p}を使う。
  \item ローカル変数は名前が同じでも、メモリーの配置場所は異なる。正確言うと、そ
	の関数が呼び出されたときのみ、ローカル変数はメモリーに割り当てられる。
\end{itemize}
%
%---------------------------------------------------------------------
\subsection{ポインター}
%---------------------------------------------------------------------
 \begin{itemize}
  \item ポインターとは、アドレスを格納する変数のことである。
  \item ポインターの宣言には、型名とアスタリスク(\tw{*})を付ける。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	int *pi;
	double *px;
 \end{verbatim}
\end{quote}
%
  \item 変数のアドレスを取り出すには、変数名の前にアンパサンド(\tw{\&})をつける。
	\tw{\&}はアドレス演算子である。以下の例では、\tw{pi}と\tw{px}がポインター
	で、変数\tw{i}と\tw{x}のアドレスを、それに代入している。
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	pi=&i;
	px=&x;
 \end{verbatim}
\end{quote}
  \item ポインターが示しているデータの値を取り出すためには、ポインター変数の前に
	アスタリスク(\tw{*})をつける。\tw{*}は間接参照演算子である。つぎの例は、
	ポインター\tw{pi}と\tw{px}が指し示しているアドレスにある値を取り出して、
	変数\tw{j}と\tw{y}に代入している。
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	j=*pi;
	y=*px;
 \end{verbatim}
\end{quote}
%
\item リスト\ref{prog:hajimete_pointer}のプログラムをよく理解すること。
\begin{list}{}{\leftmargin=7em \labelwidth=5em}
 \item[4行]整数型のポインター\tw{p}を宣言している。\tw{p}に整数型のデータの先頭
	   アドレスを格納する。
 \item[5行]整数型の変数 \tw{i} を宣言し、$(11223344)_{16}$を代入している。
 \item[7行]変数 \tw{i} の先頭アドレスをアドレス演算子 \tw{\&}により取り出し、ポインター 
	   \tw{p} に代入している。
 \item[9行]整数変数 \tw{i} の先頭アドレスを変換指定子 \%p により表示している。
 \item[10行]ポインター \tw{p} の先頭アドレスを変換指定子 \%p により表示している。
 \item[12行]整数変数 \tw{i} の値を16進数表示の変換指定子 \%0x により表示している。
 \item[13行]ポインター \tw{p} の値を16進数表示の変換指定子 \%0x により表示してい
	   る。ただし、ポインターはアドレスなので、強制型変換(キャスト)により、
	   符号なし整数にしている。
 \item[15行]ポインターが指し示すアドレスに格納されているデータを表示している。
\end{list}
 \end{itemize}
%
\lstinputlisting[caption=ポインターとアドレス,label=prog:hajimete_pointer]
{program/hajimete_pointer.c}
%
\newpage
\fbox{実行結果}
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	address i 0xbffff6b0
	address p 0xbffff6b4
	value i 11223344
	value p bffff6b0
	value *p 11223344
 \end{verbatim}
\end{quote}
%
この実行結果から、メモリーは図\ref{fig:pointer_in_memory}のようになっていること
が分かる。
%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]
  {figure/pointer_in_memory.eps}
  \caption{リスト\ref{prog:hajimete_pointer}のプログラム実行後のメモリーの内容}
  \label{fig:pointer_in_memory}
 \end{center}
\end{figure}
%
%
%=====================================================================
\end{document}



