サンプルプログラム ptr1.c, ptr2.c
(13-1)ポインタ
ポインタとはアドレス値を持つ変数のことです。
アドレス値を持っているだけではあまり意味がないのですが、
宣言時に型を指定してアドレスの中身(メモリの内容)を参照することができますのでいろいろ使えます。
ポインタの宣言の仕方
ポインタを宣言するには変数名の前に*(アスタリスク)を付けます。
int *pInt; // int型のポインタ char *pChar; // char型 〃 void *pVoid; // void型 〃 float *pFloat; // float型 〃 double *pDouble; // double型 〃
ポインタの宣言に型を指定するのは参照するメモリの内容が何であるかを指定するためです。
つまり、int型のデータが書き込まれたメモリを参照するときはintで宣言し、
float型のデータが書き込まれたメモリを参照するときはfloatで宣言します。
では実際の使い方の例です。
配列の値をポインタを使って参照してみます。
#include <stdio.h> void main( void ) { int i; int iArr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; double dArr[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; int *pInt; double *pDouble; pInt = iArr; // 配列変数名はアドレス値(固定値)を持っていますのでポインタに代入できます! pDouble = dArr; // 〃 for( i = 0; i < 10; i++ ) { printf( "i = %d, *pInt = %d, *pDouble = %2.1f\n", i, *pInt, *pDouble ); pInt++; pDouble++; } }
プログラム中のコメントにも書きましたが、配列の変数名はアドレス値を持っていますのでポインタに代入できます。
...そう、配列変数とポインタ変数の違いは持っているアドレス値が固定か可変かというだけなんですね。
ポインタの指し示すアドレスのデータを参照するときにはポインタの前に*(アスタリスク)を付けることで参照できます。
それともう一つ、ポインタに変数のアドレスを代入したい場合には、
pInt = &i;
のように変数の前に&(アンパサンド)を付けると変数のアドレス値を得ることができ、代入できます。
プログラムの実行結果は以下のようになります。
i = 0, *pInt = 1, *pDouble = 1.0 i = 1, *pInt = 2, *pDouble = 2.0 i = 2, *pInt = 3, *pDouble = 3.0 i = 3, *pInt = 4, *pDouble = 4.0 i = 4, *pInt = 5, *pDouble = 5.0 i = 5, *pInt = 6, *pDouble = 6.0 i = 6, *pInt = 7, *pDouble = 7.0 i = 7, *pInt = 8, *pDouble = 8.0 i = 8, *pInt = 9, *pDouble = 9.0 i = 9, *pInt = 10, *pDouble = 10.0
プログラム中で注意してみて頂きたい所はpIntもpDoubleもインクリメントしているだけ!という所です。
ポインタは宣言時に型を指定していますのでその型のデータ数(バイト数)が何バイトか分かっているのでインクリメントするだけで、
その型分のアドレス値を増やしてくれます。次のサンプルプログラムでアドレス値がどう変化するかをご確認ください。
#include <stdio.h> void main( void ) { int i; int iArr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; double dArr[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 }; int *pInt; double *pDouble; pInt = iArr; // 配列変数名はアドレス値(固定値)を持っていますのでポインタに代入できます! pDouble = dArr; // 〃 for( i = 0; i < 10; i++ ) { printf( "i = %d, pInt = %08x, pDouble =%08x\n", i, pInt, pDouble ); pInt++; pDouble++; }
結果は以下のような感じになると思います。
i = 0, pInt = 0061fedc, pDouble =0061fe88 i = 1, pInt = 0061fee0, pDouble =0061fe90 i = 2, pInt = 0061fee4, pDouble =0061fe98 i = 3, pInt = 0061fee8, pDouble =0061fea0 i = 4, pInt = 0061feec, pDouble =0061fea8 i = 5, pInt = 0061fef0, pDouble =0061feb0 i = 6, pInt = 0061fef4, pDouble =0061feb8 i = 7, pInt = 0061fef8, pDouble =0061fec0 i = 8, pInt = 0061fefc, pDouble =0061fec8 i = 9, pInt = 0061ff00, pDouble =0061fed0
アドレス値は実行する環境により異なるかもしれませんが、重要なのはその増分です
pIntはint型(4バイト)なのでアドレス値は4バイトずつ増えています。
またpDoubleはdouble型(8バイト)なのでアドレス値は8バイトずつ増えています。