C言語の習得にあたっての最大の難関がポインタである. 本演習では,これを突破する!
C言語は他のプログラミング言語に比べて,数学的・論理的美しさよりも, 実際にコンピュータがどういう処理をするか (ソースコードがどういう機械語に変換されるか)ということを重視している. そのため,きめの細かい効率の高いプログラムを書くことができるが, コンピュータの動作原理を知らないと,そのようなプログラムは書けないし, 読めない.この代表例がポインタである.
「コンピュータの動作原理を知らないと」といっても, CPUやメモリの仕組みを細かくまで知っている必要はない. メモリやメモリアクセスについて概念的にわかっていれば十分だろう. 本ページでは,それを理解してもらうためにイラストを多用したつもりである.
C言語を習った最初の頃に,変数とは 「数値を記憶する名前の付いた箱である」 という例えを聞いたと思う. 実際には,その箱はメモリ上に配置されており, メモリのアドレス(番地)を使っても箱を指定することができる. このアドレスを抽象化した概念がポインタである. しかし,ポインタ=アドレスと思っても間違いない.
ポインタを使えば, 変数名とは別の手段で記憶領域を指し示すことができる. ポインタの値を格納するデータ型をポインタ型と呼び, ポインタ型の変数をポインタ変数という.
メモリ上の1つのアドレスには 通常の8bit(=1byte)のビット列を記憶することができる. したがって,例えば, 整数を32bitのビット列で表現する場合には, 連続する4つのアドレスの領域を用いる.
何を指すか?が必要. 「何」とは指す対象のデータ型のこと.
型名 * 変数名;ポインタ以外の変数とまとめて宣言しても構わない.
ポインタ型の配列や, ポインタ型を指すポインタも作ることができる.
(例) int *a; int x, y, *px, *py; char c, s[100], *p; char *av[20], **aa;
ポインタ = アドレスと前述したが,正確には
ポインタ = アドレス + 何を指すか?である.
&a → 変数aのポインタ値(アドレス) *p → ポインタ変数pの指す場所に格納されている値プログラム中で
int a, *p; p = &a;という処理が実行された後では,aと*pは等価. つまり,「a = 123;」と書いても,「*p = 123;」と書いても同じ.
ポインタの宣言の時の「*」と, 指す場所の値を指定する「*」を混同しないように!
ポインタ変数は何を指しているかが重要であって, 通常はその具体的な値(=アドレス)を知る必要はない. しかし,ポインタの原理を知るために,敢えてポインタ変数の値を表示させてみる. ポインタの値を表示するには,関数printf()の書式文字列で"%p"を使う.