概ね方位不定だが多分割と偏っている
スポンサーサイト
--年--月--日 (--) | 編集 |
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


C ポインタのアドレス計算
2006年08月15日 (火) | 編集 |
盆の中で今日が一番暑かった罠。
この糞暑い中、靖国参拝に行った小泉さんお疲れ様でした。
予想通り中国や韓国が騒いでいるようで、暑苦しいやらうっとうしいやら。
この糞暑い中、よくデモとか放火とか出来るものだとある意味感心したり。
ってあっちはそんなに暑くないのか。



ま、理解出来ないものは放っておこう。

ポインタの章、最後の項目だな。
メモリのサイズとかの概念も関わってくるので面倒だが頑張るしか。

さて。
今まではポインタに先頭アドレスを代入し、後はpa++とかしてポインタのアドレスを進めて次を参照する、とかいうのを当然のように行ってきたわけだが、実際はデータ型によって格納されるメモリのサイズ?が異なる為、単純にpaに+1しただけでは参照出来ないはずなのである。
んじゃ何で見えていたのかというと、実は+1に見せかけて、内部では別の演算が行われたいたというわけなのだな。この演算に使われる、型毎に違う要素をファクタ(因子、係数を意味するそうな)と呼ぶ。

論理上は
pa++、pa=pa+1

こう記述するが、実際は
pa=pa+α

こんな感じに処理されているらしい。
前述の通りこのαはデータ型によって異なり、一般的にはchar型なら1、int型なら2、long型、float型なら4、double型なら8になる。
って入門書には書いてあるが、実は今のCではint型は4バイトなのでintも4進む。

例)
paがint型のポインタ変数で、アドレスが0x1000の時にpa++したらpaは0x1004になる

実際に見てみよう。
int型とchar型でそれぞれ配列を作り、ポインタ変数を作り、それぞれにアドレスを代入して++して先に進ませ、そのアドレスの変化を観測する。

static int a[ ]={0,1,2,3,4,5};
static char b[ ]={'a','b','c','d','e'};
int *pa;
char *pb;
pa=a;
pb=b;


ここまでで配列の宣言と初期化とポインタの宣言とアドレス代入。
後はfor文で繰り返し表示と++を行う。ループ変数iの宣言も忘れないように。

for(i=0;i<6;i++){
 printf("%x %d | %x %c\n"、pa,*pa,pb,*pb);
  pa++;
  pb++;
}


pointer_adress_test.jpgpointer_adress_test2.jpg

こんな感じ
折角だからdouble型も見てみるぜ。

static double c[]={0.0,1.0,2.0,3.0,4.0,5.0};
double *pc;
int i;
pc=c;


実数型の配列cとそのポインタpcを宣言して

for(i=0;i<6;i++){
 printf("%x %f\n",pc,*pc)
 pc++;
}


繰り返して表示。

こんな感じ。8バイトずつ進んでいる。
また、ポインタによる配列表現でやったように配列c[ ]のi番目の要素は

*(pc+i)
pc[i]


でも表現出来る為、for文の部分を

for(i=0;i<6;i++){
 printf("%x %2.1f\n",pc+i,*(pc+i));
}




for(i=0;i<6;i++)
 printf("%x %2.1f\n",pc+i,pc[i]);


に変えても同じような結果が得られる。
実数部分は桁数が多過ぎて見辛いので減らしてみた。


まとめよう。

論理上は+1の処理でも実際には+αされているんだよ!!

な、なんだってーー!?



以上。
…いや、マジでこうとしか言いようがない。
まあMMR風に言う必要は全く無かったが。
スポンサーサイト

コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。