シンプルな質問、私たちはC言語キャストで知られていないデータ型で既知のサイズでポインタをキャストできますか?
いいえすべてのポインタ型は、それが指す特定の型を持っています。これには、void *
が含まれ、その参照先のタイプ(void
)は、言語によって提供される不完全な型です。 void *
には、の変換可能なのすべての他のオブジェクトポインタ型のポインタ型がありますが、未知のデータ型へのポインタなどはありません。
一方、文字タイプ(たとえばchar *
,unsigned char *
)へのポインタを使用して任意のタイプのオブジェクトにアクセスすることは有効です。その1つの方法は、タイプが文字の配列である左辺値を使用することです。 size
の配列へのポインタep
とcp
各ポイント:
int assertEqual(void* expected, void* current, size_t size) {
unsigned char (*ep)[size] = expected;
unsigned char (*cp)[size] = current;
// ...
}
尖った-するタイプとして可変長配列型を使用する:あなたはとてもよう頼むものに非常に似た何かを得ることができタイプunsigned char
の要素。その配列タイプのサイズはsize
です。たとえば、実際にはsizeof(*ep) == size
が見つかります。つまり、指定されたサイズのオブジェクトへのポインタがあり、それを介してそのオブジェクトのバイトにアクセスすることができます。
しかし、他の人がすでに指摘しているように、あなたが尋ねるものはちょっと無意味です。2バイトのシーケンスを比較したい場合は、それらが表すオブジェクトのタイプを知らずに、memcmp()
を使用します。一方、バイトシーケンスの異なる2つのオブジェクトは、同じ型のオブジェクトとして比較されても等しいため、一般的な等価テストとしては安全ではありません。これは、浮動小数点表現が完全にインプリメンテーション依存であるため、多くの整数型がその値に寄与しないパディングビットを持つことが許可されているために発生します。
さらに、struct
およびunion
タイプには、指定されていない、必ずしも一貫した値ではないパディングバイトを含めることができます。複合型を==
演算子と比較することはできませんが、そのようなオブジェクトの表現を構成するバイト配列を比較しても、必ずしもメンバーごとにオブジェクトを比較するのと同じ結果にはなりません。
逆参照する場合は、タイプを選択する必要があります。平等は「既知の」型に対してのみ定義されます。 –
ほとんどの場合、関数は「ファンクタ」であり、その存在の全体的なポイントは型固有の比較を提供することです。つまり、関数はどの型をキャストするかを知っています。標準関数 'bsearch'がどのように機能しているかを読んでください。すべてが明確になるはずです。 – Lundin
私はポインタのサイズを指すのではなく、あなたが指しているオブジェクトのサイズを意味すると思います。 – Olaf