C言語のポインタには様々な役割がある.
本来ポインタというと4のことであるが,この演習では, まずはポインタの基本を押さえて, 1と2がきちんと使えるようになることを目指している. 3についても少しだけ紹介した. 3,4,5のポインタが使えなくても多くのプログラムを読み書きできるが, 1や2がわからないとお話にならない.
関数呼び出しにおいて, 呼び出す側と呼び出される側(関数側)との間のデータのやり取りを考える. これまでに習った方法は以下の2つである.
他のプログラミング言語では, 引数の「値渡し」と「参照渡し」を区別できるものもあるが, C言語には「値渡し」しかない. そこで,C言語で「参照渡し」と同等の機能を実現するためにポインタを用いる.
これまでは,例外として, 「配列(文字列を含む)を引数にした場合は, その中身を関数側で書き換えると呼び出し側でも変化する」 と述べてきたが,実は,関数の引数にする場合は,配列もポインタも等価なのである.
配列がメモリ上に隙間なく順に並んでいるという性質を前提として, 配列上のデータに高速かつ簡潔な表現でアクセスする手段としてポインタを用いる.
機械語によるメモリアクセスの手法を考慮しているので, 機械語に変換されたときに効率の良いプログラムになる.
手続きを簡潔な表現で記述できることが多いが, 反面,慣れていないと,それを読みこなせない.
C言語では, 変数を記憶領域(メモリ)に割り当てる方法として,主に以下の2つがある.
それでは不便なので,標準ライブラリには,OSの助けを借りて, 実行時に記憶領域を指定した量だけ確保する関数が用意されている (確保するだけでなく,解放する関数もあり).
ところが,このような領域に変数を割り当てることはできない. そこで,このような領域を「指す」ためポインタを用意し, 間接的な表現でそこへアクセスする.
Pascalなどの他のプログラミング言語で使われる「本来の意味のポインタ」. 「リスト」や「木構造」のような少し複雑な「データ構造」 を実現するためには欠かせない.
プログラミング言語を一通り習い終わった後に, さらにプログラミングの授業があるとすれば, たいてい「アルゴリズムとデータ構造」を学ぶことになるが, そのような時には必ずこのポインタが登場する. しかし,この演習では,ポインタのこの役割は, 構造体を学ぶ回に少し紹介するにとどめる.
コンピュータによっては,メモリ空間内のあるアドレスに, 入出力のインターフェースが割り当てられることがある. 例えば,メモリのある番地の内容が画像取り込み装置が取り込んだ画像の明度のデータだったり, あるアドレスに値を書き込むことが装置への信号の出力だったりする.
ポインタ値としてメモリ番地を直接代入することは, 本来のC言語の仕様の範疇を越えているが,現実には, ハードウェアに関わるプログラムを作るにあたっては多用される方法である.