ポインタのポインタを理解するための動作確認（メモ）

c言語初学者の例にもれずポインタ迷子になりました。

・ポインタのポインタ
・ポインタの配列
・配列のポインタへのキャスト
あたりを勉強し始めたくらいです。
（既に呼び方が合ってるかも怪しい・・・）

参考にしたページ↓
[配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)

動作を確認しながら現状の理解をメモ。
（おそらく間違いだらけです。コメントでご指摘もらえるとうれしいです。）

#「配列の配列」とポインタ
以下の配列の配列（多次元配列）とポインタを使っていろいろ動作確認。

```c
	char ss[5][6]	= {"abc", "cdef", "fgh", "hijkl", "lm"};
	char *p  = (char *)ss;
```
**【現状の理解】**
ss[5][6]　　・・・要素数が5で、「要素数6のchar型配列」型の配列
*p　　　　   ・・・charへのポインタ型
(char *)ss　・・・ssを(charへのポインタ型)にキャスト。つまり&ss[0][0]


以下のプログラムでポインタが保持するアドレスの値を確認

```c
	for(i = 0; i < 10; i++){
		printf("*p + %d = %c    "	, i, *p + i);
		printf("*(p + %d) = %c"		, i, *(p + i));
	}
```

```:実行結果
*p + 0 = a    *(p + 0) = a
*p + 1 = b    *(p + 1) = b
*p + 2 = c    *(p + 2) = c
*p + 3 = d    *(p + 3) = 
*p + 4 = e    *(p + 4) = 
*p + 5 = f    *(p + 5) = 
*p + 6 = g    *(p + 6) = c
*p + 7 = h    *(p + 7) = d
*p + 8 = i    *(p + 8) = e
*p + 9 = j    *(p + 9) = f

```
結果から、
・\*p　は、s[0][0]の先頭アドレスの値なので'a'
・\*p + 1 は、'a' + 1　と同じことを指している。つまり\*pはchar型。
・\*(p + i)も、もちろんchar型
・\*(p + i)は ポインタ\*pの先頭アドレスからi個進んだ先頭アドレスを指したうえで、その値を示している（値はchar型）
・ポインタの示す先頭アドレスに「\*」をつけると、そのアドレスの値を示す

ついでに、サイズも確認

```c
	printf("sizeof(*p) = %u\n", (unsigned)sizeof(*p));
	printf("sizeof( p) = %u\n\n", (unsigned)sizeof(p));

```

```:実行結果
sizeof(*p) = 1
sizeof( p) = 8
```
・*pはchar型なので、1byte
・ pはアドレスを格納しているので、アドレスのサイズが表示される。（アドレスの中身の型は無関係）この処理系ではアドレスは8byte表示

#ポインタの配列
今度はポインタの配列を使って動作確認

```c
	char *tt[5]		= {"ABC", "CDEF", "FGH", "HIJKL", "LM"};
	char **q = tt;
```
**【現状の理解】**
\*tt[5]　・・・charへのポインタ型の配列。要素数は5
**q ・・・charへのポインタへのポインタ型

以下のプログラムでアドレスやら値やらを確認。

```c
	for(i = 0; i < 5; i++){
		printf("q   + %d = %p    "			, i, q + i);
		printf("*q  + %d = %5s    "			, i, *q + i);
		printf("*(q + %d) = %5s    "		, i, *(q + i));
		printf("*(q + %d) + %d = %5s    "	, i, i, *(q + i) + i);
		printf("**q + %d = %c    "			, i, **q + i);
		printf("*(*(q + %d) + %d) = %c"		, i, i, *(*(q + i) + i));
		putchar('\n');
	}
```

```:実行結果
q + 0 = 000000000061FDE0    *q + 0 =   ABC    *(q + 0) =   ABC    *(q + 0) + 0 =   ABC    **q + 0 = A    *(*(q + 0) + 0) = A
q + 1 = 000000000061FDE8    *q + 1 =    BC    *(q + 1) =  CDEF    *(q + 1) + 1 =   DEF    **q + 1 = B    *(*(q + 1) + 1) = D
q + 2 = 000000000061FDF0    *q + 2 =     C    *(q + 2) =   FGH    *(q + 2) + 2 =     H    **q + 2 = C    *(*(q + 2) + 2) = H
q + 3 = 000000000061FDF8    *q + 3 =          *(q + 3) = HIJKL    *(q + 3) + 3 =    KL    **q + 3 = D    *(*(q + 3) + 3) = K
q + 4 = 000000000061FE00    *q + 4 =  CDEF    *(q + 4) =    LM    *(q + 4) + 4 = s[5][6]：     **q + 4 = E    *(*(q + 4) + 4) = s

```
実行結果の考察
・q + i は、ポインタのポインタが指す先頭アドレスからi個すすんだところのアドレス（格納されている値がアドレスなので、8byteずつすすむ）
・\*q + i は、ポインタのポインタが指すアドレスからi個すすんだところのアドレスの中身（*qはcharへのポインタ型なので、+1すると1byteすすむ。）
・%s は、指定されたアドレスの文字から、終端文字までの文字を出力する
・\*q + 3 は終端文字、\*q + 4 は次の文字列になっているということは、文字列のサイズはバラバラになっている。もし各文字列のサイズが同じなら、\*q + 4 にも終端文字が格納されているはず。（配列では空いたところにはNULL文字が入る）
・ポインタには「要素数」という概念がない。
・*(q + i)は、ポインタのポインタが指す先頭アドレスからi個すすんだところのアドレス中身（初期化の時点でq + 4 まではアドレスを格納してある）
・**q + i は、ポインタのポインタが指すアドレスの中身の中身ニ +1した値。(**qは純粋なchar型の値なので、文字コードに従った出力になる）
・文字列中の'a'と文字コードの'a'の指すアドレスは違う。（これ重要！）

サイズは以下のような感じ

```c
	printf("sizeof(q)   = %u\n", (unsigned)sizeof(q));
	printf("sizeof(*q)  = %u\n", (unsigned)sizeof(*q));
	printf("sizeof(**q) = %u\n\n", (unsigned)sizeof(**q));
```

```:実行結果
sizeof(q)   = 8
sizeof(*q)  = 8
sizeof(**q) = 1
```
q・・・charへのポインタへのポインタ型なので先頭アドレスのサイズを指す。
\*q・・・charへのポインタのポインタ型の中身(\*)なので、中身のcharへのポインタ型の先頭アドレスのサイズを指す。
**q・・・charへのポインタのポインタ型の中身(\*)の中身(\*)なので、中身のcharへのポインタ型の先頭アドレスの中身の値(char型)のサイズを指す。

ああ、日本語が崩壊していく・・・

#配列とポインタについてのまとめ（現状の理解）
**配列**
・値を格納する（アドレスの書き換えはダメ！）
・要素数がある（その分、要素数の乗算でサイズが大きくなる）
 ⇒ 自由度が低く、管理コストがかかるが、扱いは簡単なイメージ
（20人を5チームに分けるので4人ずつ整列しなさい！的な）

**ポインタ**
・アドレスを格納する（つまり占有領域が8バイトしかなくてうれしい！）
・要素数がない（配列のように使う時も、あくまで「アドレスの指定」という概念）
 ⇒ 自由度が高く、管理コストが少なくてすむが、扱いは難しいイメージ
（とりあえず少人数のチームを何個か作りたいんだよねえ。リーダーはお前！あとは適当にやってちょ～。的な。）

##思った事、メモ
命令単体での動作確認だけじゃ、深い理解にはならないと思った。（もちろんそれもめちゃくちゃ大切だが。）
基礎知識がついたら簡単なアプリケーションを組まないとなあ。

**ポインタを勉強して分からなくなるまでの道のりをメモ**
・は～ん、ポインタってアドレスを指すのね。以外に簡単じゃん。
・実は配列もアドレスを指してたのね。なるほど。
・あれ、ポインタと配列って同じじゃんか！
・ポインタと配列同じじゃないな・・・違いはアドレスを格納する領域があるか、ないかか。簡単じゃん！
・ポインタのポインタ・・・ポインタの配列・・・なんだか気分が悪くなってきた。オェッ。
・ポインタのサイズっていつも8byte。配列と違って「要素数」とかいう概念もないのね。
・は～ん、ポインタってアドレスを指すのね。なんとなく分かった・・・気がする・・・【←イマココ】