腕時計の沼、オーディオの沼、PCの沼。『タクジの沼』

ポインタ

オブジェクトとアドレス

その内容によって、値を表現することができる実行環境中の記憶域の領域「m, n」などの変数をオブジェクトと呼びます。
個々のオブジェクトの場所を何らかの方法で表します。そのことをアドレスと呼びます。

アドレス演算子

オブジェクト x のアドレスは &x によって取り出せます。

[整数]
printf( "n1の値 = %d\n", n1 );
[アドレス]
printf( "n1のアドレス = %p\n", &n1 );

※演算子とオペランド
演算子とは演算を行うための記号。演算の対象となる式はオペランド

ポインタ

"指すもの"という意味
Type型のポインタpの値が、Type型オブジェクトxのアドレスであるとき、「pはxを指す」と表現します。

int	n;
int	*ptr;

ptr = &n;	/* ptrはnを指す */

※キャストによる型変換
キャスト演算子と呼ばれる()演算子は、次の形式で利用します。
(型)式

間接演算子

ポインタに対して適用される演算子は間接演算子と呼ばれる単項*演算子です。 ポインタに対して間接演算子を適用して、ポインタが指すオブジェクトを間接的にアクセスすることを参照外しと呼びます。

バイトとアドレス

アドレス付与の対象となる単位は、バイト(byte)
多くの環境では、1byteは8bitで構成されています。(言語では「少なくとも8である」と定義されています) その値は "limits.h" ヘッダ中でCHAR_BITとして定義されています。

オブジェクトの大きさとsizeof演算子

sizeof(型名)	/* ビットはなくバイト */
sizeof	式	/* 式は()で囲まなくてよい */

ポインタの宣言と初期化

複数のポインタを宣言するときは、それぞれの変数に*を付けます。

式の評価

式とは、①変数②定数③変数や定数を演算子で結合したもの。
評価とは、式の値を調べること。

ポインタから整数値での変換

ポインタから整数値への型変換において必要な型は処理系に依存します。 また、不十分な大きさの整数型への変換は定義されていません。 ポインタの値を整数値に変換する場合は、なるべくunsigned long型にキャストするべきである。 (最も大きな非負の整数値を表現できるため)

関数の引数としてのポインタ

関数間の引数の受け渡しは、値渡しで行われます。 関数を呼びだす側は実引数の式の「値」を渡し、その値は呼び出される関数の仮引数に代入されます。 そのため、仮引数は実引数の「コピー」に過ぎません。

ポインタの値渡し

オブジェクトへのポインタを仮引数に受け取れば、間接演算子*を適用することによってそのオブジェクトをアクセスできます。

値渡しのメリット

引数の受渡しの全てが「値渡し」によって行われるからこそ、呼び出し側は引数を安心して関数に渡せます。 また、値渡しのメリットを利用すれば、プログラムはコンパクトで効率よいものとなる可能性があります。

配列と添字演算子

配列の全要素は同じ型であり、添字演算子[]を用いてアクセスできます。 先頭要素の添字は0であり、その後方の要素の添字は一つずつ増えていく整数であります。

int     a[5];
要素型   要素数

a[0]
a[1]
a[2]
a[3]
a[4]
配列の全要素は、連続した領域に配置されます。

配列名の解釈

原則として、配列名はその配列の先頭要素へのポインタと解釈されます。

配列名が先頭要素へのポインタとみなされない文脈

  1. アドレス演算子&のオペランドであるとき(配列全体のポインタ)
  2. sizeod演算子のオペランドであるとき(配列全体の大きさ)

ポインタに整数を加減算したポインタ

ポインタpが配列中の要素eを指すとき

  1. p+iは、要素eのi個だけ後方の要素を指すポインタ
  2. p-iは、要素eのi個だけ前方の要素を指すポインタ

間接演算子と添字演算子

ポインタpが配列中の要素eを指すとき

  1. 要素eのi個だけ後方の要素を表す *(p+1)は、p[i]と表記
  2. 要素eのi個だけ前方の要素を表す *(p-1)は、p[-i]と表記
[例]
a[0] = *(a + 0) = p[0] = *(p = 0)

要素を指すポインタの範囲

配列の要素数がnであるとき、
a[0] ~ a[n-1] = &a[0] ~ &a[n]のn+1個

配列とポインタの相違点

代入演算子 = によって配列をまるごとコピーすることはできません。 (for文などによって実現する必要がある)

ポインタ同士の比較

ポインタの指すオブジェクトが同一であるかないかは、等価演算子 == と != によって判定できます。 同一配列内の要素を指すポインタの大小関係の判定は、関係演算子 <, <=, >, >= によって行います。 その際、より後ろ側のオブジェクトを"大きい"と判断します。