1

このコードは Turbo C で実行されますが、gcc コンパイラでは実行されません
エラー: '*' トークンの前の構文エラー

#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;
}

Turbo C の出力は :4, 4 , 2
です。Turbo C の出力について教えてください。

4

3 に答える 3

6

修飾子hugefarおよびnear、は非標準です。そのため、Turbo C で動作する可能性がありますが、他のコンパイラ (gcc など) で動作することに依存することはできません。

于 2011-11-06T11:29:44.587 に答える
5

Borland の DOS 用 C/C++ コンパイラは、複数のメモリ モデルをサポートしていました。

メモリ モデルは、ポインターを介してコードとデータにアクセスする方法です。

DOS はいわゆるCPU で動作し、aと an のreal modeペア(通常はそれぞれ 16 ビット長) を介してメモリにアクセスするため、メモリ アドレスは当然 4 バイト長になります。segment valueoffset value

ただし、セグメント値を常に明示的に指定する必要はありません。プログラムがアクセスする必要があるすべてのものが 1 つsegment(16 バイト境界に配置された 64KB のメモリ ブロック) に含まれている場合、1 つのセグメント値で十分であり、CPU のセグメント レジスタ (CS、SS、DS、ES) にロードされます。 、プログラムは16ビットのオフセットのみを使用してすべてにアクセスできます。ところで、多くの.COMタイプのプログラムはまさにそのように動作し、1 つのセグメントのみを使用します。

したがって、メモリにアクセスするには、明示的なセグメント値を使用する方法と使用しない方法の 2 つの方法があります。

これらの行で:

char huge *near *far *ptr1;
char near *far *huge *ptr2;
char far *huge *near *ptr3;

修飾子farhugeおよびが指すオブジェクトのnear近接を指定します。これらは、およびオブジェクトがプログラムのメイン/現在のセグメントから「遠く離れている」ことをコンパイラに伝えます。オブジェクトはプログラム自身のセグメント内の「近く」にあり、2 バイトのポインターで十分です。ptr1ptr2ptr3*ptr1*ptr2*ptr3

これは、さまざまなポインターのサイズを説明しています。

プログラムをコンパイルするために選択したメモリ モデルに応じて、関数およびデータ ポインターはデフォルトでnearorfarまたはhugeのいずれかになり、デフォルト以外のポインターが必要でない限り、それらを明示的に指定する必要がなくなります。

プログラム メモリ モデルは次のとおりです。

  • tiny: すべてに対して 1 つのセグメント。ポインターの近く
  • 小: 1 コード セグメント、1 データ/スタック セグメント。ポインターの近く
  • 中: 複数のコード セグメント、1 つのデータ/スタック セグメント。far コード ポインター、near データ ポインター
  • コンパクト: 1 つのコード セグメント、複数のデータ セグメント。Near コード ポインタ、Far データ ポインタ
  • 大: 複数のコードおよびデータ セグメント。遠いポインター
  • huge: 複数のコードとデータ セグメント。巨大なポインター

Hugeポインターには、ポインターの特定の制限はありませんがfar、操作が遅くなります。

于 2011-11-06T12:37:06.210 に答える
1

変数の間にカンマを入れるのを忘れました:)。スコープが同じ場合、変数に同じ名前を付けることはできません。

于 2011-11-06T12:47:33.717 に答える