ぼんさい塾

ぼんさいノートと補遺に関する素材や注釈です.ミスが多いので初稿から1週間を経た重要な修正のみ最終更新日を残しています.

ポインタ

2013-08-27 13:49:40 | 暮らし
progC.pdf
progC-s.pdf
記事一覧
 
                       仮引数での宣言

progC-s.pdf に「D8R%ポインタ」を追加しました.「ポインタは難しくない」と書いた資料もありますがやはり難しいと思います() --- 考えて分からなくても,コンパイラがあれば これ と同様にして自分で調べることができます.
(1) 「int x[3][4];」のとき "xはアドレスである" といっても sizeof(x) == 48. (2) 「int f(int y[100][5]){・・・}」の y はポインタで sizeof(y) == 4. (3) 「y[100][5]」は「y[ ][5]」と等価であるが「y[-100][5]」はエラー.(4) f の呼び出し「f(x)」はエラーにならないが「int z[6];」の「f(z)」はエラー. (5) 仮引数の宣言では *p == p[ ] であるが,(p[ ] == p[0] でもいいのに)実行文「p[ ] = 7;」はエラー --- (処理系がどこまで面倒を見ているか)考えても分かりませんね.調べるしかありません!

参考資料([n]は本文でも引用):
[1] ポインタ (プログラミング) - Wikipedia
  http://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
逆に言えば、整数の様な自由な四則演算は制限されており、座標に対する演算と同じ演算しか出来ないという事である。
[2] BCC Developer - Hi-HO
  http://www.hi-ho.ne.jp/jun_miura/bccdev.htm
専らこれで確認しています.*.c であればCとしてコンパイルしますが「//」も使えます(C99で追認)
[3] プログラミング言語C―ANSI規格準拠― 第2版
  http://www.kyoritsu-pub.co.jp/bookdetail/9784320026926
全般に参照していますが,補足(7)の引用上明示.
[4] ポインタ虎の巻
  http://www.nurs.or.jp/~sug/soft/tora/index.htm
初級篇目次(1-9), 中級篇目次(1-7)
[5] ポインタ(pointer)
  http://www.cc.kyoto-su.ac.jp/~yamada/programming/pointer.html
メモリモデル,変数のメモリサイズとアドレス,変数とポインタ,ポインタ型変数,
配列とポインタ,ポインタへのポインタ
[6] C言語:ポインタ入門
  http://www.geocities.jp/debu0510/personal/c_pointa.html
基本,メモリの動的確保,関数へ参照渡しもどきをする,関数へのポインタ,
ポインタへのポインタ,voidへのポインタ,コールバック関数1,複雑な宣言,初期化
---------
[7] なぜポインタを使うのか? - Yahoo!知恵袋
  http://note.chiebukuro.yahoo.co.jp/detail/n3121
[8] C言語 ポインタ完全制覇
  http://kmaebashi.com/programmer/pointer.html
ポインタが難しいのではない。 C言語の、配列とポインタにかかわる文法が混乱しているだけだ。
[9] プログラム初心者にC言語のポインタを不本意ながら教える羽目になった ...
  http://d.hatena.ne.jp/kura-replace/20120611/1339376977
本稿は「ポインタの解説」ではなく「C 言語のポインタの教え方」です。
[10] C/C++は永久に不滅です! - Part4 誰もがつまずくポインタを完璧理解 ...
  http://itpro.nikkeibp.co.jp/article/COLUMN/20061206/256198/
考え方さえわかってしまえば、ポインタはそれほど難しいものではありません。
次ページ以降はITpro会員(無料)の方のみお読みいただけます。

補足:(1) 多数の資料がありますが,とりあえず上記資料だけ掲げておきます.
(2) [%4] の表現は ここ で紹介した資料と少し変えています.
---------
(3) [%1] の記号《p》は一般には通用しません.
(4) [%11] の「処理系に依存」は“ビッグエンディアン/リトルエンディアン”.
(5) [%2] の x[3][4] の初期値は {{5, 6, 0, 0}, {7, 8, 9, 0}, {0, 0, 0, 0}}なので,p[6] (== p[4+2]) の値は x[1][2] (== 9).「int (*q)[2] = x+1;」なら q[0][0] == 7,q[0][1] == 8,q[1][0] == 9.
(6) 局所変数の宣言でも「int q[ ][4] ={{α, β};」は「int q[2][4] ={{α, β};」と同じなのでエラーにはなりませんが,このときの q は配列の先頭アドレスでポインタではありません(e.g. 代入不能).
(7) 「char (*(*x[3])())[5];」は K&R-2,5.12 からの引用です.
(8) 関数の(プロトタイプ)宣言については次回述べます.
------------------------------------------------------------------
#include < stdio.h>//HTMLタグに化けないようSPを挿入
int main(void){
  int x[3][4]={{5,6},{7,8,9}}, i, k;
  printf("sizeof(x) is %d\n", sizeof(x));
  for(i = 0; i < 3; i++){
    for(k = 0; k < 4; k++){
      printf("%d, ", *(&x[0][0] + i*4 + k));
    }
    printf("\n");
  }
  printf("%d:f(x)\n", f(x));
  return 0;
}
int f(int p[100][5]){int i, k;
  printf("sizeof(p) is %d\n", sizeof(p));
  for(i = 0; i< 3; i++){
    for(k = 0; k < 4; k++){printf("%d, ", p[i][k]);}
    printf("\n");
  }
  return p[0][1];
}