C言語関係掲示板

過去ログ

No.1017 ポインタ演算

[戻る] [ホームページ]
No.1306

ポインタについて質問があります
投稿者---まながつお(2004/02/12 10:24:13)


 こんにちは、このサイトにはよくお世話になっています。
今日はポインタについての質問があります。

 このサイトを含めていろいろなC言語サイトを見ていますが、
ポインタを使用した例文には初期設定した変数に応じて
ポインタ変数も同じ型で初期設定されていました。
(int型ならポインタもint型、 char型ならポインタもchar型)

そこで疑問に思いました。
ポインタが変数の番地を相手に仕事をするのであれば、
int型の変数にはint型のアドレスが、char型の変数には
char型のアドレスが付くという事なのでしょうか?



No.1307

Re:ポインタについて質問があります
投稿者---おでん(2004/02/12 11:19:06)


>
> このサイトを含めていろいろなC言語サイトを見ていますが、
>ポインタを使用した例文には初期設定した変数に応じて
>ポインタ変数も同じ型で初期設定されていました。
>(int型ならポインタもint型、 char型ならポインタもchar型)
>
>そこで疑問に思いました。
>ポインタが変数の番地を相手に仕事をするのであれば、
>int型の変数にはint型のアドレスが、char型の変数には
>char型のアドレスが付くという事なのでしょうか?
>
“char型のアドレスが付く”というのがよく分からないのですが?

例えばpというポインタがchar型の配列のアドレスを持っているとします。
その時、p++またはp+1という動作はどうなればいいのでしょう?
・・・当然、配列の次の要素を指して欲しいですよね?
もし、ポインタの指している要素の型が分からなければ、
p++の演算はどうすればいいのでしょう?
何処を指せばいいか分からなくなりますね?
なので、ポインタ演算時にはポインタが指している要素の型が必要となります。
#void *は特殊です。(そのままでは使えません)

以下の宣言があった場合、
char * cp ;
cp++ ; ←charが1バイトだと1バイトだけ進む。
int * ip ;
ip++ ; ←intが4バイトだと4バイトだけ進む。
という事になります。
演算だけを考えれば、ポインタ++は、その要素のサイズ分進む事になります。


No.1308

Re:ポインタについて質問があります
投稿者---YuO(2004/02/12 22:42:10)


>ポインタが変数の番地を相手に仕事をするのであれば、
>int型の変数にはint型のアドレスが、char型の変数には
>char型のアドレスが付くという事なのでしょうか?

まず,根本的な間違いから。

ポインタ型の変数が保持するのは,
ポインタという名前で呼ばれるオブジェクトを参照するための値です。
#変数の番地を使う,というのはあくまで実装詳細に過ぎない。

型によってポインタの大きさが異なる,ということもあります。
ref) C FAQ 5.17


そして,ポインタ演算というのは,ポインタが配列の要素を指しているときに使う物です。
#一応,配列の要素でない場合は要素数1の配列と考えて処理することになっている。

ポインタと整数の加減算は,
  • ポインタPが配列aのp番目の要素を指している
  • 加減する値q
がある時,P±qまたはq+Pは,配列aの(p±q)番目の要素を指すポインタになります。
配列からはみ出た場合は,配列の末尾の次の要素にあたる位置を除くと,
その演算は未定義の動作となります。

また,ポインタ同士の減算では,
  • ポインタPが配列aのp番目の要素を指している
  • ポインタQが配列aのq番目の要素を指している
として,P-Qはp-qに等しくなります。
PとQが指すオブジェクトが,同じ配列に含まれる要素でない場合,
配列の末尾の次の要素にあたる位置を除くと,その演算結果は未定義となります。


結局,番地がどうこう,とかアドレスがどうこう,という話は動作の中に出てきません。
それらは,単に実装の詳細でしかないので,あまり気にすることはないと思います。