7

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

#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

配列 a[] 、つまり 1,2,3,4 の要素をピン留めしないのはなぜですか?

4

4 に答える 4

15

追加するarr にキャストする必要がありますj。最小限の修正は次のとおりです。

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

しかし、次のように書く方が明確だと思います:

x = ((int *)arr)[j];
于 2012-01-11T00:45:27.567 に答える
6

void *C では無効なポインター演算を実行しています。

GNU C (gcc 拡張の C) では、実際に許可されており、thesizeof (void)は 1 と見なされます。

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

「加算および減算演算は、void へのポインターおよび関数へのポインターでサポートされています。これは、void または関数のサイズを 1 として扱うことによって行われます。」

于 2012-01-11T00:50:21.087 に答える
2

C 標準では の算術演算の動作が定義されていないため、演算を行う前にまず別のポインター型void *にキャストする必要があります。void *

一部のコンパイラは [拡張として] のポインター演算をvoid *と同じようchar *に扱うため、各 '+1' は、ポイント先のオブジェクトのサイズではなく、アドレスを 1 だけ増加させます。ただし、これは標準化されていないため、この動作に依存することはできません。

于 2012-01-11T00:50:45.847 に答える
1

void ポインターに数値を追加しないでください。前にキャストします。( x = *((int *)arr+j);)

ポインターに数値を追加すると、コンパイラーはこの数値にポイントされている型のサイズを乗算するため、間違った型へのポインターに数値を追加すると、間違った結果が得られます。

私の記憶が正しければ、void* への追加は違法ですが、一部のコンパイラは正確な数をバイト単位で追加します (char* のように)。`

于 2012-01-11T00:50:02.350 に答える