2012-03-24 5 views
7

なぜ2つのアドレスの違いが間違っていますか? http://codepad.org/NGDqFWjJポインタ/アドレスの違い

#include<stdio.h> 
int main() 
{ 
    int i = 10, j = 20; 
    int *p = &i; 
    int *q = &j; 
    int c = p - q; 
    printf("%d\n", p); 
    printf("%d\n", q); 
    printf("%d", c); 
    return 0; 
} 

出力:無関係なポインタ上で実行するとき

-1083846364 
-1083846368 
1 

答えて

17

は、まず、ポインタ演算が定義されていません。

第2に、意味があります。ポインタを減算すると、バイト数ではなく、それらのアドレス間の要素数が取得されます。

あなたは

char *p1 = &i, *p2 = &j; 

と違う結果になるだろうことをしようとした場合。


補足として、ポインタを印刷するときは%pを使用してください。

+0

厳密に言えば、私がこれまで使ってきたすべての実装は「正しいこと」です。実際にOPのもそうです。 –

+0

@CarlNorumうん、私は編集しました。 – cnicutar

+0

入手しました。ありがとう! – Ava

2

厳密に言えば、あなたのプログラムは、無関係なポインタのポインタ算術のためにいくつかの種類の未定義の動作を引き起こします。そして、あなたのprint文でフォーマット文字列と引数が不一致です。しかし、それらが修正されても、同じ結果が表示されます。差が1であるのは、指し示された型のサイズの単位で結果が得られるためです。intは4バイト型なので、4バイト離れたポインタint *を引くと結果は1になります。

6

他の人が言っているように、得られる結果は、ポインターが指している型のサイズの倍数になります。それらをcharポインタにキャストすると、結果はバイト単位で取得されます。また、ptrdiff_t typeを使用する必要があります。そのため、64ビットポインタを持つシステムでは、型は結果を保持するのに十分な大きさでなければなりません。

ptrdiff_t c = (char*)p - (char*)q; 

も同じ配列になっていない2つの値のアドレスの差をとることは、標準で定義されていませんが、ほぼすべてのシステム上で作業を行うことに注意してください。

+0

これを試みると、 'voidへのポインタの算術演算 'のエラーが発生します。 –

+0

'void *'ポインタの算術演算は、特定のフラグを持つ(ある)コンパイラでのみサポートされている[非標準的な振る舞い](https://stackoverflow.com/a/3524270/1289657)であることがわかります。代わりに 'char *'ポインタの代わりに答えを変更しました。これは正しく動作し、標準的な動作です。 – AgentME