「unsigned int」の範囲は、「int *」または任意のポインターの範囲と等しいため、どちらも 64 ビット プラットフォームで 4 バイトを使用するためです。Cのポインターをunsigned intに置き換えることはできますか??
4 に答える
についてはそのような保証はありませんunsigned int
。uintptr_t
C99 では、プラットフォームに関係なくポインタを保持する特別な型が導入されました。<stdint.h>
このタイプを使用するには、ヘッダーを含める必要があります。
短い答え:いいえ。
少し長い回答: がunsigned int
特定のプラットフォームで有効なポインタ値を保持できるという保証はありません (64 ビット プラットフォームでは の範囲外のアドレス値を持つ可能性が高いとすでに何人かが指摘していますunsigned int
)。これは、異なる型へのポインターが異なるサイズと表現を持つ可能性があるという事実によってさらに複雑になります。
ポインターはアドレス値をエンコードするだけではありません。また、型をエンコードします。これは、ポインター演算と配列添字に関係します。たとえば、次の宣言があるとします。
char *cp = 0x4000;
int *ip = 0x4000;
float (*dap)[10] = 0x4000;
3 つのポインター ( cp
、ip
、dap
) はすべて、同じ値 で始まります0x4000
。ただし、各ポインターに 1 を追加すると、異なる結果が得られます。32 ビットint
とfloat
型を仮定すると、次のようになります。
cp + 1 == 0x4001
ip + 1 == 0x4004;
dap + 1 == 0x4028;
に 1 を追加するcp
と次のchar
オブジェクトのアドレス (0x4001) がip
得られ、 に 1 を追加すると次のint
オブジェクトのアドレス (0x4004) が得られ、 に 1 を追加するとオブジェクトdap
の次の 10 要素配列のアドレスfloat
(0x4028)が得られます。 . これにより[]
、各ポインターで演算子を使用できます。期待する結果 (ポインターに続く 'th 要素)を書き込んcp[i]
で取得できます。ただし、これらすべてのポインターを として入力すると、添字演算子を使用できず、それらに 1 を追加しても、必ずしも次のオブジェクトのアドレスではなく、次のバイト アドレスしか得られません。 ip[i]
i
unsigned int
int
64Bit アーキテクチャで 4 バイトであることを確認することさえできません! タイプの制限は絶対に実装と環境が定義されているためです。標準は、どの値が少なくともどの範囲を持たなければならないかという制限を与えるだけです。それで全部です。int
64 ビットで 8 バイト、10 バイト、13 バイト、または環境がそのサイズを望んでいるものは何でもかまいません。ですので、もちろん交換可能です。ただし、無効なアラインメントで終わるか、データが失われる可能性があります。異なるサイズのタイプの各割り当てとして持つことができます。ただし、少なくともポインター値を値に割り当てることはできint
ます。しかし、これは ISO/IEC9899 で有効な値型からポインター型への唯一の変換でもあります。