//このコードの出力は 4 4 2 ? なぜptr3が2なのかわかりませんか?助けてください
#include<stdio.h>
int main()
{
char huge *near *far *ptr1;
char near *far *huge *ptr2;
char far *huge *near *ptr3;
printf("%d, %d, %d\n", sizeof(ptr1), sizeof(ptr2), sizeof(ptr3));
return 0;
}
near
、far
、およびhuge
ポインターは非標準です。
それらをサポートする実装 (通常は非常に古い x86 システムの場合) では、メモリ内の特定の場所をセグメントとオフセットで指定できます。ポインターにはオフセットのみがnear
含まれ、セグメントは暗黙のままになります。far
したがって、ポインターよりも必要なスペースが少なくなります。
最新のコンパイラは、これらのキーワードを使用しません。新しいコンパイラを見つけることをお勧めします。無料で利用できるものがたくさんあります。
詳細については、この質問を参照してください。
ちなみに、printf の"%d"
形式には type の引数が必要int
です。異なる型であるsizeof
type の結果を生成します。通話を次のようにsize_t
変更できます。printf
printf("%d, %d, %d\n", (int)sizeof ptr1, (int)sizeof ptr2, (int)sizeof ptr3);
(これを行う現代的な方法は次のとおりです。
printf("%zu, %zu, %zu\n", sizeof ptr1, sizeof ptr2, sizeof ptr3);
near
しかし、ポインタとポインタをサポートする実装は、C99 で導入されたfar
をサポートするほど最新ではない可能性があります。)"%zu"
混乱の層を取り除くためだけに、他の答えを使用できます。
ポインターの宣言は次のnear
ようになります。
type near* variable;
またはこのように:
near type* variable;
type
任意のタイプはどこにありますか。あなたの例では、type
それ自体がポインター型であるため、誰かがあなたを混乱させようとしています: char far *huge *
. ただし、何を指していても、near
ポインターは 2 バイトを占有します。
(そのような構成が実際のコードに現れる可能性はないため、誰かが意図的にあなたを混乱させようとしていると思います)
古いコンパイラ (turbo c の可能性があります) を使用していると思います。最新のコンパイラはこの機能をサポートしていません。
Nearポインターにはセレクターがありません。暗黙のセレクターがあります。286 以前では仮想アドレス空間の 64k にアクセスでき、386 以降では 4Gb のアドレス空間にアクセスできます。
farポインターには明示的なセレクターがあります。ただし、それらに対してポインター演算を行う場合、セレクターは変更されません。
巨大なポインターには明示的なセレクターがあります。セレクターが変更される可能性がありますが、それらに対してポインター演算を行うと。
これは、古い DOS コンパイラで使用されていた概念ですfar
near
。huge
これらが内部でどのように実装されているかについてのすべてを説明します。この実装により、このようなサイズになります。