例:
sizeof(char*)
4を返します。、、、int*
私long long*
が試したすべてのことを行います。これに例外はありますか?
17 に答える
あなたが得る保証はそれsizeof(char) == 1
です。の保証を含め、その他の保証はありませんsizeof(int *) == sizeof(double *)
。
実際には、ポインターのサイズは 16 ビット システム (見つかった場合) では 2、32 ビット システムでは 4、64 ビット システムでは 8 になりますが、特定の値に依存しても何も得られません。サイズ。
プレーンな x86 32 ビット プラットフォームでも、さまざまなサイズのポインターを取得できます。例として、次のように試してください。
struct A {};
struct B : virtual public A {};
struct C {};
struct D : public A, public C {};
int main()
{
cout << "A:" << sizeof(void (A::*)()) << endl;
cout << "B:" << sizeof(void (B::*)()) << endl;
cout << "D:" << sizeof(void (D::*)()) << endl;
}
Visual C++ 2008 では、メンバー関数へのポインターのサイズとして 4、12、および 8 が得られます。
Raymond Chen はここでこれについて話しました。
すでに投稿されたリストのもう 1 つの例外です。32 ビット プラットフォームでは、ポインターは4バイトではなく6 バイトを取ることができます。
#include <stdio.h>
#include <stdlib.h>
int main() {
char far* ptr; // note that this is a far pointer
printf( "%d\n", sizeof( ptr));
return EXIT_SUCCESS;
}
このプログラムを Open Watcom でコンパイルして実行すると、6 になります。これがサポートする far ポインターは 32 ビットのオフセットと 16 ビットのセグメント値で構成されているためです。
64ビットマシン用にコンパイルしている場合は、8になる可能性があります。
技術的に言えば、C標準はsizeof(char)== 1のみを保証し、残りは実装次第です。しかし、最新のx86アーキテクチャ(Intel / AMDチップなど)では、かなり予測可能です。
プロセッサが16ビット、32ビット、64ビットなどと説明されているのを聞いたことがあるでしょう。これは通常、プロセッサが整数にNビットを使用することを意味します。ポインタはメモリアドレスを格納し、メモリアドレスは整数であるため、これはポインタに使用されるビット数を効果的に示します。sizeofは通常バイト単位で測定されるため、32ビットプロセッサ用にコンパイルされたコードはポインタのサイズを4(32ビット/バイトあたり8ビット)と報告し、64ビットプロセッサ用のコードはポインタのサイズを8と報告します。 (64ビット/バイトあたり8ビット)。これは、32ビットプロセッサの4GBのRAMの制限が原因です。各メモリアドレスが1バイトに対応する場合、より多くのメモリをアドレス指定するには、32ビットより大きい整数が必要です。
ポインタのサイズは基本的に、それが実装されているシステムのアーキテクチャに依存します。たとえば、32 ビットのポインターのサイズは 4 バイト (32 ビット) で、64 ビット マシンでは 8 バイト (64 ビット) です。マシンのビットタイプは、それが持つことができるメモリアドレスに他なりません。32 ビット マシンは2^32
アドレス空間を持つことができ、64 ビット マシンは最大2^64
アドレス空間を持つことができます。したがって、ポインタ (メモリ位置を指す変数2^32 for 32 bit and 2^64 for 64 bit
) は、マシンが保持するメモリ アドレス ( ) のいずれかを指すことができる必要があります。
このため、ポインタのサイズは 32 ビット マシンでは 4 バイト、64 ビット マシンでは 8 バイトであることがわかります。
16/32/64 ビットの違いに加えて、さらに奇妙なことが発生する可能性があります。
sizeof(int *) が 1 つの値、おそらく 4 になるマシンがありましたが、sizeof(char *) の方が大きいです。バイトではなく単語を自然にアドレス指定するマシンは、C/C++ 標準を適切に実装するために、単語のどの部分が本当に必要かを指定するために、文字ポインターを「拡張」する必要があります。
これは、ハードウェア設計者がバイト アドレス指定可能性の価値を学んでいるため、現在では非常に珍しいことです。
人々が 64 ビット (または何でも) システムについて言ったことに加えて、オブジェクトへのポインター以外の種類のポインターがあります。
メンバーへのポインターは、コンパイラーによる実装方法に応じて、ほぼすべてのサイズになる可能性があります。必ずしもすべて同じサイズであるとは限りません。POD クラスのメンバーへのポインターを試してから、複数の基底を持つクラスの基底クラスの 1 つから継承されたメンバーへのポインターを試してください。なんて楽しい。
私が思い出したことから、それはメモリアドレスのサイズに基づいています。したがって、32ビットアドレススキームを使用するシステムでは、sizeofは4バイトを返すため、4を返します。
一般に、異なるプラットフォームでコンパイルすると、sizeof(ほとんどすべて)が変化します。32ビットプラットフォームでは、ポインタは常に同じサイズです。他のプラットフォーム(64ビットが明白な例です)では、これは変更される可能性があります。
Windows 32 ビット マシンの Turbo C コンパイラでは、ポインターと int のサイズは 2 バイトです。
したがって、ポインタのサイズはコンパイラ固有です。ただし、一般に、ほとんどのコンパイラは、32 ビットでは 4 バイトのポインター変数をサポートし、64 ビット マシンでは 8 バイトのポインター変数をサポートするように実装されています)。
そのため、ポインタのサイズはすべてのマシンで同じではありません。
いいえ、ポインタのサイズはアーキテクチャによって異なる場合があります。多くの例外があります。
ポインタのサイズが4バイトである理由は、32ビットアーキテクチャ用にコンパイルしているためです。FryGuyが指摘したように、64ビットアーキテクチャでは8が表示されます。
ポインターは、アドレスの単なるコンテナーです。32 ビット マシンでは、アドレス範囲は 32 ビットであるため、ポインターは常に 4 バイトになります。64 ビット マシンでは、64 ビットのアドレス範囲がある場合、ポインターは 8 バイトになります。
完全性と歴史的な関心のために、64 ビットの世界では、主に Unix タイプのシステムと Windows の間で、LLP64 および LP64 と呼ばれる long 型と long long 型のサイズに関する異なるプラットフォーム規則がありました。ILP64 という名前の古い標準でも、int = 64 ビット幅になりました。
Microsoft は longlong = 64 ビット幅の LLP64 を維持しましたが、移植を容易にするために、long は 32 のままでした。
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64