*配列は要素型のオブジェクトが連続してメモリに記憶されるデータであり,配列型は式で使うと第1要素のアドレスに変換されることを見ました。ということは,配列型を式で使えば第1要素の値が入っている場所に直接アクセスできるという意味です。それならば,そのアドレスのメモリ箇所に入っている値にもアクセスできるはずです。
+------------+ アドレス | 0xbffffa18 | 式 | str | →→ +------------+ ↓ 間接参照 値 | 'A' | ↓ 式 | str[0] | ←← +------------+ char str[] = "ABCDEFG"; の場合
アドレスからそのメモリ箇所に記憶される値を参照することを「間接参照」(indirection)と言います。間接参照するための演算子が「間接演算子」です。
■間接演算子(Indirection Operator)
*オペランド
オペランドはポインタ型であること。
オペランドが「T へのポインタ」型のアドレスの場合,間接演算子はそのアドレスのメモリ箇所に記憶されている値をT 型で戻します。
/* Example 10.3 */
#include <stdio.h>
int main(void)
{
       char str[] = "ABCDEFG";
       printf("str[0] = '%c' [%p]\n", *str, str);
       return 0;
}
これは,Example 10.1 において,間接演算子を使って配列の第1要素の値を出力させる例です。実行結果です。
str[0] = 'A' [0xbffffa18]
str 自体がアドレス 0xbffffa18 を指し,そのメモリ箇所に記憶されている値 'A' を間接演算子で求めた訳です。
/* Example 10.4 */
#include <stdio.h>
int main(void)
{
       unsigned int m[5] = {3, 7, 10};
       printf("m[0] = %d [%p]\n", *m, m);
       return 0;
}
こちらは Example 10.2 において,m[0] を *m に置き換えて配列の第1要素の値を出力させるものです。実行結果です。
m[0] = 3 [0xbffffa78]
+------------+------------+------------+------------+ | 0xbffffa78 | 0xbffffa79 | 0xbffffa7a | 0xbffffa7b | アドレス | m | | | | +------------+------------+------------+------------+ | 0x00 | 0x00 | 0x00 | 0x03 | 値 |<--------------------- m[0] ---------------------->| +------------+------------+------------+------------+ 間接参照 *m → m[0]
m は intへのポインタ型なので,*m は int型です。奥山研究室では sizeof(int) = 4 ですので,それは m[0] に等しいです。