2012-02-09 22 views
0

C言語では、structへのポインタはvoid *に変換され、その逆も可能です。また、言語では、定義されていない場合でもstructへのポインタを定義することができます。コンパイラはこれらの構造体について何も知らないので、ポインタの物理的表現は同じでなければならないと私は思います。 2つの別々のモジュールにこれらの行を考えてみましょう:構造体とキャストへのポインタ

/* FILE1.c */ 
void *mem = ...; //Points to a suitable memory block 
struct s1 *p1; //No implementation given for struct s1 
void *mem2; 

p1 = (struct s1 *)mem; 
mem2 = &p1; 


/* FILE2.c */ 
extern void *mem2; 
struct s2 { /*...fields...*/ }; 
struct s2 *p2; 

p2 = *(struct s2 **)mem2; 

は、すべてのプラットフォーム上で動作することができ、このコードは、メモリブロックが(例えばmalloc(sizeof(struct s2))によって割り当てられた)struct s2を含むのに十分な大きさであることを提供?

つまり、へのポインタのように、struct s1構造体へのポインタを含むメモリセルを再解析するのは正しいですか?

(免責事項:私は、これはポインタと遊ぶのが非常に奇妙な方法であることを完全に認識しています、私の質問は、理論的である)

答えて

2

のようにそれを使用し、ポインタは同じサイズや表現を持つ必要はありません。

sizeof (int *)は、たとえばsizeof (double *)と異なる場合があります。

唯一の要件は次のとおりです。

  • void *char *signed char *unsigned char *は 同じ表現を持っています。

  • 構造体へのポインタは同じ表現をしています。

  • ユニオンへのポインタは、同じ表現をしています。

+0

'sizeof(int *)'が 'sizeof(double *)'と異なる場合の例を挙げることができますか? – mikithskegg

+0

歴史的に、ある(非常に古い)Lispマシンは36ビットの単語と "タグ付き"アドレスを持っていました:プレーンアドレスの場合は32ビット、データタイプタグの場合は4ビット。したがって、ポインタにはポインタの型に関する情報が含まれており、キャスト操作は一般的にビットのコピーではありませんでした。私は今日、同様のアーキテクチャを持つCPUがあるかどうかはわかりません。 –

+0

@mikithskegg for 'int *'と 'double *'私は分かりませんが、例えばCray PVPシステムは 'char *'の64ビット表現と 'double *'の32ビット表現を持っています。 – ouah

0

はい、あなたは正しいです。すべてのポインタは同じサイズと構造を持ちます。彼らはコンパイラの "心"だけが異なる。

+0

これは当てはまりませんが、ポインタ型は同じ表現を持つ必要はありません。 – ouah

0

はい、可能です。

ポインタは、その表現では、任意のデータ型のメモリロケーションアドレスを保持する整数です。

0

これは、一部のデータを抽象化するときに役立ちます。あなたが持つことができます。

struct s1 
{ 
    char header[4]; 
    int type; 
    char data_max[200]; 
}; 

struct s1_type1 
{ 
    char header[4]; 
    int type; 
    char data_of_some_implementation[80]; 
    char data_of_other_implementation[120]; 
}; 

そしてCではこの

struct s1 data; 
int nb = read(fd, &data, sizeof(data)); 
if (nb == sizeof(data)) 
{ 
    if (data.type == 1) 
    { 
    do_something_special((struct s1_type1*)&data); 
    } 
} 
関連する問題