こんにちは、南 晴輝 ( みなみ せいき )です。
今回は、C言語を使う時に、重要なポイントです。
組み込みシステムで、本当に良くつかわれる、 構造体 のアクセスにポインタは
なくてはなりません。
配列とポインタ
1つ1つの変数に対して、ポインタを使用する利点はありません。
ポインタは配列や後述する構造体や 共用体と組み合わせて初めて利点が生まれるのです。
添え字を使った場合と、ポインタを使った場合の配列の中身を表示するプログラムを示します。
#include <stdio.h>
void main(){
int a[10] = { 5, 4, 9, 1, 10, 7, 8, 3, 2, 6 };
int i;
for ( i = 0 ; i < 10 ; i++ )
printf("%d ", a[i]);
}
#include <stdio.h>
void main(){
int a[10] = { 5, 4, 9, 1, 10, 7, 8, 3, 2, 6 };
int *p = a;
int *pend = a + 10;
for ( ; p < pend ; p++ )
printf("%d ", *p);
}
実は、配列の変数に対して添え字を使わない形の変数そのもの(ここではa)はその配列の
先頭アドレスを指すのです。
そして配列とは、メモリー上に連続して領域が取られるので、アドレスを1つ分(1バイトではない)増やせば、
配列の次の要素が得られるのです。
これまでのことを整理するためにlong型のポインタとchar型のポインタの違いを
見てみることにします。
コンピュータによってポインタの大きさは異なりますが、ここでは現在主流である
32bitと仮定して解説します。
上図のように、long型ポインタもchar型ポインタも、ポインタは32bit(4byte)変数です。
char型のサイズは8bit(1byte)なので、char型ポインタを1つ進めると、
ポインタの値は 1増えます。
これに対してlong型の場合は、32bit(4byte)の大きさなので、long型ポインタを1つ進めると、
ポインタの値は4(byte)増えます。1(byte)とか2(byte)増やすことは基本的にはできません。
char型ポインタにキャストして増やせば1増やすことも可能ですが意味がありません。
もし1(byte)とか2(byte)とか増えたら、無効な変数へのアクセスをしてしまうことになります。
次に、ポインタの演算について説明します。これから説明することは
コンパイラによって 多少違う点があるかもしれません。
ポインタはアドレスなので、アドレスの計算に意味がないような演算は許されません。
例えば、ポインタの乗算、除算は、意味がないので許されません。またポインタ同士の加算も
意味がありませんが、減算は要素数を知るために必要なのでできます。
あくまでも要素数になり、バイト数ではないことに注意が必要です。
さらに、ポインタ同士の比較は同じ型のポインタどうしてなければできません。
これらをまとめると以下のようになります。
許される演算
同じ型のポインタ同士の減算
同じ型のポインタ同士の比較
ポインタと整数の加算
ポインタから整数の減算
最後までお読みくださり、ありがとうございます。
必ず毎日ブログを更新していますので、是非見に来てください。
よろしくお願いします。
南 晴輝