腕時計の沼、オーディオの沼、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 式 /* 式は()で囲まなくてよい */
複数のポインタを宣言するときは、それぞれの変数に*を付けます。
式とは、①変数②定数③変数や定数を演算子で結合したもの。
評価とは、式の値を調べること。
ポインタから整数値への型変換において必要な型は処理系に依存します。 また、不十分な大きさの整数型への変換は定義されていません。 ポインタの値を整数値に変換する場合は、なるべくunsigned long型にキャストするべきである。 (最も大きな非負の整数値を表現できるため)
関数間の引数の受け渡しは、値渡しで行われます。 関数を呼びだす側は実引数の式の「値」を渡し、その値は呼び出される関数の仮引数に代入されます。 そのため、仮引数は実引数の「コピー」に過ぎません。
オブジェクトへのポインタを仮引数に受け取れば、間接演算子*を適用することによってそのオブジェクトをアクセスできます。
引数の受渡しの全てが「値渡し」によって行われるからこそ、呼び出し側は引数を安心して関数に渡せます。 また、値渡しのメリットを利用すれば、プログラムはコンパクトで効率よいものとなる可能性があります。
配列の全要素は同じ型であり、添字演算子[]を用いてアクセスできます。 先頭要素の添字は0であり、その後方の要素の添字は一つずつ増えていく整数であります。
int a[5]; 要素型 要素数 a[0] a[1] a[2] a[3] a[4] 配列の全要素は、連続した領域に配置されます。
原則として、配列名はその配列の先頭要素へのポインタと解釈されます。
[例] a[0] = *(a + 0) = p[0] = *(p = 0)
配列の要素数がnであるとき、 a[0] ~ a[n-1] = &a[0] ~ &a[n]のn+1個
代入演算子 = によって配列をまるごとコピーすることはできません。 (for文などによって実現する必要がある)
ポインタの指すオブジェクトが同一であるかないかは、等価演算子 == と != によって判定できます。 同一配列内の要素を指すポインタの大小関係の判定は、関係演算子 <, <=, >, >= によって行います。 その際、より後ろ側のオブジェクトを"大きい"と判断します。