配列とポインタの関係について,情報を整理する前に,過去のエントリを読み直してみました.
上の2つの中に,整理しておきたいなあと思っていたことの95%が詰まっていました.うーん.
ただそれでも,「学び方」については,書けそうな気がします.Cの基本,具体的にはコンパイル・実行の方法,変数の宣言,算術型,制御文,演算子を学んだ状態を出発点として,自分の授業の進め方から離れて,列挙してみます.
- Cにおいて配列とポインタを学ぶ理由を確認します.多くの実用的なプログラムで両者が適切に使われていること,なので自分も読んで書けるようになりたいと思うこと,うまく使えば計算機の適性(メモリ,レジスタなど)に合った(=効率のよい)プログラムを作れること,あたりでしょうか.
- 配列はどの本を読んでも学び方は違いませんかね.int a[3];と宣言してもa[3]は参照・代入してはいけないことが最低限です.配列を使ったプログラムに慣れ親しんだあとに,「sizeof(配列変数)/sizeof(配列変数[0])」という式の意味*1を押さえておきたいところです.
- 次は,ポインタです.「配列じゃない変数を指し示すポインタ」と「配列を指し示すポインタ」を,分けて理解していきます.前者については単項の&と*の使い方を確認し,後者についてはp[i]が*(p+i),pが&p[0]と等価なこと*2とp++の意味*3を押さえます.また,ポインタを介して値を変更すると,元の変数(配列変数の要素を含む)への代入をしていないのに,値が変わってしまう点も,大事なことです.
- 関数呼び出しで,配列やポインタがどう使われるかを学びます.重要なのは,それぞれの変数の「有効範囲」と「生存期間」です*4.関数の中で(ローカル変数として)配列変数を宣言するときと,仮引数として配列変数を宣言するときとで,違いを確認します.
- 多次元配列(配列の配列)と,そのポインタを用いたアクセスについて学びます.関数呼び出しで多次元配列を渡すにはどう書けばよいか,なぜその書き方でよいのかを理解します.「2次元配列」と「ポインタの配列」のそれぞれを使って,a[i][j]と書いて参照・代入のできるプログラムを作りながら,データ構造の違いをイメージします.
- K&Rを含む複数の本や,JIS X 3010を読んで,配列とポインタをめぐる用語や概念を自分なりに整理します.「配列変数」という表記一つだけでも,大いに学べるでしょう*5.
*1:どんな値になるのか(what),どのような計算によってその値になるのか(how),なぜそんな式を書かないといけないのか(why)の3点が含まれています.
*2:ここについてもっと面白いことが書けそうだけど今は時間がないンで脚注に残しとく.
*3:先ほどの脚注のwhat/how/whyに加えて,何が変わって何が変わらないのかを知っておく必要があります.インクリメント演算子は現れませんが,ポインタがからんだ「変わる」「変わらない」の議論は,http://d.hatena.ne.jp/takehikom/20080803/1217711739で試みています.
*4:「有効範囲(スコープ)」のみでは,配列のいわゆる参照渡しを用いたときに,関数のスコープ外にある配列領域を書き換えてよいことが,説明できません.
*5:私自身の未解決問題は「ポインタ値」にあります.