ポインタ
アドレス演算子とポインタ演算子
プログラムで扱うデータ変数等はコンピュータのメモリ主記憶上に格納される。例えば、
「 " <0!3」のように整数型の変数<0!を宣言すると、図に示すようにメモリ上に整数 を格納するのに必要なバイトの領域が確保され、そこに変数<0!の値が格納される 。
100
␒ᆅ ኚᩘi _val ࡢ್ࢆ᱁⣡࣓ࣔࣜ
int i_val;
104
␒ᆅ図) 変数の値を格納する領域 コンピュータでこれらのデータを処理する際には一般に
データの内容そのもの変数の値等
データが格納されているメモリ上のアドレス番地 データが使用しているメモリ領域の大きさバイト数
等の情報が必要になることがある。#言語では、変数に対して、これらの情報を次のように記述 する。
表記法 意味
= 変数の値
7= 変数のアドレス変数の値を格納するメモリのアドレス
H.=/ 変数の値を格納するのに必要なメモリ領域の大きさバイト 変数のアドレスを表すために用いる「7」をアドレス演算子と呼ぶ 。
図"では、番地に格納される例を挙げているが、具体的な番地は#やコンパイラ、プログラム内での変 数の宣言位置等により変化する。
$型の変数にキーボードから進数の値を入力するときに「%&'()*」を用いるが、この「)」は変数
のアドレスを表している。このように、%関数では、値を読み込む変数の指定に、変数名ではなく変数のアドレスを 指定する必要がある。
プログラム例
)&#'
*
型の変数
$ 型の変数 $
/ 型の変数 /
+ .0 変数 に値 .0 を代入する
$ + 10 変数 $ に値 10 を代入する
/ + 22 変数 / に値 22 を代入する
&3 + 453 ' 変数 の値を浮動小数点で出力
&3$ + 453 $' 変数 $ の値を進数で出力
&3/ + 453 /' 変数 / の値を文字として出力
&36 + 453 6' 変数 のアドレスを1進数で出力
&36$ + 453 6$' 変数 $ のアドレスを1進数で出力
&36/ + 453 6/' 変数 / のアドレスを1進数で出力
&3/&' + 4/53 /&'' 変数 のためのメモリ領域の大きさ
&3/&$' + 4/53 /&$'' 変数 $ のためのメモリ領域の大きさ
&3/&/' + 4/53 /&/'' 変数 / のためのメモリ領域の大きさ
,
実行結果
-7.8 0
+ .0
$ + 10
/ +
6 + 90:
6$ + 90:;
6/ + 90:
/&' + ;
/&$' + :
/&/' +
-7.8
プログラム例の実行結果より、このプログラムでは、図に示すように、2 型の変数 は4<** <番地よりバイトの領域に値が格納され、$型の変数は4<** <番地よ りバイトの領域に値が格納され、.型の変数は4<** <*番地の バイトに値を格納し ていることが分かる 。なお、$*文でアドレスを 進数で出力するための書式制御文字列は
「=」である。また、メモリ領域の大きさ>*4等を$*文で 進数で出力するための書 式制御文字列は「=>」である。
"進数は+,% %, 'のように先頭に+をつけて表す。また、%は進数の に対応する。なお、一般 に、番地の値は、#のバージョンやコンパイラの種類とバージョン等によって異なるので必ずしも実行結果に示す値と同 じになるとは限らない
’A’
1.25
65
図 ) 変数のアドレスと領域の大きさ
練習 アドレス演算子等の意味を考えながらプログラム例を実際に実行せよ。レポート提出は 不要。
ポインタとは、メモリ上のアドレス番地を表すものである。ポインタを値として持つ変数の ことをポインタ変数と呼ぶ。ポインタを用いて、ポインタが指しているアドレスに格納されている データを参照することが出来る。
変数をポインタ変数とすると、「」は変数の値ポインタメモリ上のアドレスを表し、
「-」はポインタ変数が指している場所アドレスに格納されているデータを表す。ここで、「-」 はポインタ演算子と呼ばれる。
ポインタ変数の値は単にメモリのアドレスを示しているだけなので、その場所に格納するデータ の型を明示的に宣言する必要がある 。例えば、.型や$型や2 型のデータへのポイン タを格納するポインタ変数は、各々次のように宣言する 。
< 型へのポインタ変数<の型宣言
< 型へのポインタ変数<の型宣言
< 型へのポインタ変数<の型宣言
ポインタ変数も「変数」であるので、ポインタ変数にアドレス演算子7や>*演算子を適用 すると、各々ポインタ変数の値を格納するメモリのアドレスやポインタを格納するのに必要な領域 の大きさを表すことが出来る。
データが格納されているアドレスが分かってもそこに格納されているデータの型が分からないと正しく解釈すること ができない正しいデータの値は得られない。
例えば、「 」は、「変数が指している場所には-型のデータが格納されている」ことを表して いる。
$#のマシンでは、アドレスは$で指定するので、ポインタを格納するのに$ .$必要である。" $
#のマシンでは、アドレスを" $で指定するので、ポインタを格納するのに" $/.$必要である。
また、変数に対して、「7=」は変数のアドレス変数へのポインタを表しているので、
「-7=」は変数の値即ち、「=」を表している事になる。
例えば、 78のもとで、
<# 型の変数 <# の型宣言
< 型へのポインタ変数 < の型宣言 のような宣言で、変数の値を格納するアド
␒ᆅ
= &i_ptr
␒ᆅ
= &i_val i_val:
i_ptr:
࣓ࣔࣜ
␒ᆅ
50
100
*i_ptr
図 ) ポインタ演算子とアドレス演算子 レスが 番地、変数の値を格納するアド
レスが 番地だったとする。また、
番地の 3の領域に整数が格納されてお り、 番地の 3の領域に整数 が格納されているものとする図参照。こ の時、変数 の値やそれらにアドレ ス演算子やポインタ演算子を適用した時の値を 表 に示す。
表 ) アドレス演算子とポインタ演算子の値 表現 値 コメント
<# 変数 の値整数
6<# 変数 のアドレス
<# 使用不可
6<# 変数 の値
< 変数の値メモリのアドレス番地
6< 変数のアドレス
< 変数が指している所に格納されている値整数
6< 変数の値メモリのアドレス番地
プログラム例
<# 型の変数 <# の型宣言
< 型へのポインタ変数 < の型宣言
)&#'
*
&3 " 6<# + 453 6<#' 型変数 <# の番地を1進で出力
&3 =" 6< + 453 6<' ポインタ変数 < の番地を1進で出力
&3 >" /&<#' + 4/53 /&<#'' <#に必要な領域の大きさ
&3 ?" /&<' + 4/53 /&<'' <に必要な領域の大きさ
< + 6<# 変数 <# の番地をポインタ変数 < に代入
< + . ポインタ変数 < が指している場所に「.」を格納
&3 @" <# + 453 <#' 変数 <# の値を進で出力
&3 A" < + 453 <' ポインタ変数 < が指している場所に
格納されている値を進で出力
&3 B" < + 453 <' ポインタ変数 < の値を1進で出力
&3 C" 6<# + 453 6<#' 変数 <# の番地に
格納されている値を進で出力
<# + 0 変数 <# に「0」を代入
&3 D" <# + 453 <#' 変数 <# の値を進で出力
&3 E" < + 453 <' ポインタ変数 < がさしている場所に
格納されている値を進で出力
&3 F" < + 453 <' ポインタ変数 < の値を1進で出力
&3 G" 6<# + 453 6<#' 変数 <# の番地に
格納されている値を進で出力
,
実行結果
-7.8 1
" 6<# + 9
=" 6< + 1;
>" /&<#' + :
?" /&<' + ;
@" <# + .
A" < + .
B" < + 9
C" 6<# + .
D" <# + 0
E" < + 0
F" < + 9
G" 6<# + 0
-7.8
プログラム例では、最初に$型変数<0!と$型へのポインタ変数<の番地とサイ ズ必要な領域の大きさをプリント:?;〜:@;してから、$型へのポインタ変数に$型 変数 のアドレスを代入している。このため、この代入以降は、-<は<0!を表すこと になる。したがって、-<にを代入すると<0!の値もとなり、<0!にを代入すると
-<の値もとなる実行結果 と図参照。
また、実行結果より、$型へのポインタを格納するのにバイト必要であることも分かる実 行結果の:@;参照。
注意「" -<3」のような$型へのポインタ変数の宣言は、メモリ上に$型へのポインタ を格納する領域を確保するだけであり、整数を格納する領域は確保されず、また<の初期値 も不定である。したがって、「-<」を使用する前に「" <0!3」のような宣言で実際に整 数を格納する場所を確保し、そのアドレスを「< 5 7<0!3」によりポインタ変数<に 代入しておく必要がある。
演習 アドレス演算子やポインタ演算子等の意味を考えながらプログラム例を実際に実行せよ。
実行結果から、使用したマシンの78が 78であるか 78であるかを判定せよ。レポー トには実行環境(プロセッサ、78のバージョン、使用した#コンパイラのバージョン)も記載す ること。
この実行結果は" $#のもとでの実行結果の例である。#の種類やバージョン、コンパイラの種類やバージョ ンによって、一般に実行結果は異なる。
0コンパイラのバージョンは、「 」や「 」を実行すれば出力される。
i_ptr:
i_val:
i_ptr:
i_val:
i_ptr:
i_val:
i_ptr:
i_val:
図) 変数 の値の変化
演習 型の変数とにキーボードから数値を入力し、これらの数値の和を 型の変数 に代入して、 の値を出力するプログラムを作成せよ。プログラムの作成にあたっては、変 数へのポインタ変数を各々作成し、可能な限りそれらのポインタ変数を用いてプログラム すること。