2012-01-11 7 views
3

整数配列へのvoidポインタを使用しようとしていましたが、配列をintにキャストし直して印刷できるかどうかを確認しようとしました。しかし、それは私にいくつかランダムな価値を与えている。私はどこに間違っているのか教えていただけますか?配列へのvoidポインタの使用

#include<stdio.h> 
#include<stdlib.h> 

int main(){ 
    int a[5]; 
    int x; 
    int j; 

    a[0]=1; 
    a[1]=2; 
    a[2]=3; 
    a[3]=4; 

    void *arr=a; 

    for(j=0;j<4;j++){ 
     x = *(int *)(arr+j); 
     printf("%d",x); 
    } 
    return 0; 
} 

出力がこれです:

133554432131072512 

は、なぜそれが[]すなわち1,2,3,4、配列の要素をpintingされていませんか?

+1

数値を出力する書式文字列に改行を入れることで出力を改善できます: 'printf("%d \ n "、x);'。 –

+0

Yupp.私はこの機能を別のプログラムでテストするのに役立つように書いているので、書式設定に集中していませんでした。 –

答えて

10

arrの前に、を追加すると、jが追加されます。ここでは、最小限の修正である:

x = *(((int *)arr)+j); 

が、私はそれを書くことが明確だと思う:

x = ((int *)arr)[j]; 
+0

チャームのように働いた。ありがとう、トン。 –

+0

私はなぜ*(int *)(arr + j)が間違っているのだろうか?あなたは私を説明できますか? –

+0

@AnushaPachunuri:私の答えを見てください。しかし、要約すると、 'void *'に数字を加えることができないので間違っています。 'void *' *を最初に*変換してから番号を追加する必要があります。 – dreamlax

1

あなたがvoidポインタに番号を追加しないでください。それを前にキャストする。 (x = *((int *)arr+j);

ポインタに数値を追加すると、コンパイラはこの数値にポインティングされている型のサイズを掛けます。間違った型へのポインタに数値を追加すると間違った結果になります。

私が正しく覚えていれば、void *に追加するのは不正ですが、いくつかのコンパイラは正確なバイト数を(char *のように)加算します。あなたはGNU C(gccの拡張子を持つC)ではC.

には有効ではありませんvoid *上のポインタ演算を行っている `

5

、それが実際に許可されているとsizeof (void)は1

と考えられています

http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

「加算および減算動作は を無効にするためのポインタにし、関数へのポインタに支持されている。これは、のサイズを処理することにより行われますvoidまたは1の関数の "

+1

+1: 'void *'の算術演算はGCCの拡張であることを指摘しています。 –

1

C標準はvoid *の算術のための振る舞いを定義していないので、あなたはそれで算術演算を実行する前に、別のポインタ型最初にごvoid *をキャストする必要があります。

一部コンパイラ[拡張として】char *同じvoid *のポインタ演算を治療するため、各‘ +1 ’だけではなく、尖った、物体の大きさによって、1アドレスを増加させるであろう。これは標準化されていませんが、この動作に頼ることはできません。

+0

ああ、ポインタ演算はvoid *ポインタには当てはまりません。まあ、私はポイントを参照してください。素晴らしい説明をありがとう。 –

+0

ISO/IEC 9899:1999。 §6.2.5¶19void型は、空の値の集合で構成されています。 が完了できない不完全な型です。_20で、関数型、オブジェクト型、または不完全な型から派生した_ポインタ型が追加されます。 型... _不完全な型は明らかにありませんオブジェクト型であるため、 'void *'をオブジェクト型へのポインタとして扱うことはできません。さらに、両方のオペランドが算術型を持たなければならないか、または一方のオペランドがオブジェクト型へのポインタでなければなりません。それで、あなたは 'void *'で算術演算を行うことができません。 。 –

+0

@JonathanLeffler:この動作はC標準では定義されていませんが、明示的に未定義ではありません。通常、Cの実装がそのような動作を行い、拡張機能と呼ばれる領域です。 – dreamlax

関連する問題