C言語研修(基礎編)
〜ポインタ〜

変数の実態

 ・変数とは値を格納する箱のようなもの
 ・現実問題として変数に格納した値はどこに存在するのか?
  −変数は理論的な概念である
  −(物理的な)コンピュータを意識すると・・・

変数の実態
 ・変数に格納した値はコンピュータ上のメモリ空間のどこかに格納されている
 ・変数はメモリへの窓口である

アドレスについて
 ・すべてのメモリ(箱)にはアドレスと呼ばれる番号がそれぞれついている
  −アドレスはメモリ空間内の特定の場所をあらわしている
 ・1つのコンピュータ内に同じアドレス(番号)は存在しない

変数の実態(まとめ)
 □変数はメモリへの窓口である
 □メモリにはアドレスと呼ばれる番号がついている
        ↓
 □変数にもアドレスがついている
 □格納されている(アドレス)を知らなくてもメモリに値は格納できる

ポインタ演算子(その1)
・ポインタを扱う演算子(その1)
 演算子   機能
  &     アドレス取得             読み方 &:アンパーサンド

 使い方 &iValue, &fDate, $piArray[3]
 補足 配列変数に対しては津上は使用しない
    (要素に対しては使用する場合あり)     配列内部の中身を要素という
 
ポインタとは
・メモリ空間内の特定の場所(アドレス)を表すもの
・メモリ内のデータを直接操作できる
・高級言語にアセンブラ(機械語)的な機能を融合

ポインタ変数
 ・ポインタ(アドレス)を格納するための変数
 ・ポインタ変数の宣言
	char *pcVariable;
	int *piVariable;
	double *pfVariable;
 ・プレフィックスの例として型を表すプレフィックスの前にpをつける
     注意int* piValue, piA;  ←piValueがポインタとして宣言
         int *iValue, piA;    上と同意

ポインタ変数について
 ・ポインタ変数に変数のアドレスを代入するには代入演算子(=)を使用する
	piVariable = &iValue;
 ・ポインタ変数には型がある
  −同じ型の変数のアドレスを格納する
 ・ポインタ変数はポインタ(アドレス)のみ格納できる
  −実際の数値は格納できない
 
 
変数のアドレスを代入するイメージ
piVariable = &iValue; のイメージ

     iValue [   10   ] 1000番地 
                ・    |
                ・    |変数のアドレス(=1000番地)
                ・    |をpiVariableに代入
 piVariable [  1000  ]   ←  
   ↑これも別のアドレスをもっている

ポインタ演算子(その2)
・ポインタを扱う演算子(その2)
演算子 機能
 *  ポインタで指し示すアドレスに格納されている値を取得

ポインタ変数を宣言する時に使用した * と混同しないこと

演算子を使用したイメージ

*piVariableのイメージ
           1000番地
     iValue [   10   ]   ←
                ・    |
                ・    |piVariableで示すアドレス
                ・    |(1000番地)の中身(=10)
 piVariable [  1000  ]   ―  

演算子使用時の注意点
 ・ポインタ変数に*演算子を使用する前には必ず有効な
  ポインタ(アドレス)をポインタ変数に設定しておかなければならない

 ・有効なポインタ(アドレス)とは
  −ポンイタ変数とは別に宣言した変数へのポインタ(アドレス)
  −OSに要求して確保した有効なメモリ領域へのポインタ(アドレス)

変数の遠隔操作
 ・変数のアドレスをポインタ変数に格納しそのポインタ変数に
  対して*演算子で値を操作すると元の変数にその操作が反映される
 ・関数の『参照渡し(Call by Reference)』と密接に関係してる

変数の遠隔操作のイメージ
*piVariable = 20;のイメージ
           1000番地
     iValue [   10   ]   ←
                ・    |piVariableで示すアドレス
                ・    |(=1000番地)の中身(=10)を
                ・    |20に変更
 piVariable [  1000  ]   ―  

配列変数の実態
 ・通常の変数はメモリへの窓口だった
   →配列変数も当然メモリへの窓口である
 ・配列変数は通常の変数に比べるとより密接にメモリと結びついている
 ・配列変数はポインタ(アドレス)を保存している
  −配列変数の要素は通常の数値を保持している

puts()の内部の動き
 ・指定された場所(アドレス)から'\0'に出会うまで画面に文字を表示する
          [0] [1] [2] [3] [4] [5] [6]...  [255]
 pszBuffer A   B   C   D   \0
           ・−−−−−−−→
 ・配列の先頭からではない

pszBuffer + i の意味
pszBuffer   +1  +2  +3 
       ↓  ↓ ↓ ↓
      [0] [1] [2] [3] [4] [5] [6]...  [255]
        A   B   C   D   \0
        ・−−−−−−−→   +0の場合
          ・−−−−−→   +1の場合
             ・−−−→   +2の場合
          
        pszBuffer+1
            ||
        &pszBuffer[1]
        
配列変数をポインタ変数に代入する
・配列変数の型と同じ型のポインタ変数に代入する
・配列変数自体がアドレスを保持しているので&演算子は必要ない
	int piArray[10], *piVariable;
	piVariable = piArray;

[]演算子
・配列の添え字を表す[]は演算子である
・[]演算子は別の演算子を利用して表現できる
	pasBuffer[i] = *(pszBuffer + i)
・指定されたアドレスからi個移動した場所におあるメモリの中身

char pszBuffer[256];
     ~~~~~~~~~
     アドレス
     char型のアドレス
             ~~~~~~~~
               ↓
             ポインタ
           ↓
     char型のポインタ