13

任意のデータ型のアドレスを保持する必要がある場合は、そのデータ型のポインターが必要です。

しかし、ポインターは単なるアドレスであり、アドレスは常にint型です。では、なぜデータ型の保持アドレスにはその型のポインターが必要なのでしょうか?

4

7 に答える 7

18

いくつかの理由があります:

  • すべてのアドレスが同じように作成されるわけではありません。特に、非フォン ノイマン (ハーバードなど) アーキテクチャでは、コード メモリ (多くの場合、定数を格納する場所) へのポインタとデータ メモリへのポインタは異なります。
  • アクセスを正しく実行するには、基になる型を知る必要があります。たとえば、 a の読み取りまたは書き込みは、 a の読み取りまたは書き込みとcharは異なりdoubleます。
  • ポインター演算を実行するには、追加情報が必要です。

C では、「単にポインター」を意味する というポインター型があることに注意してくださいvoid*。このポインタを使用してメモリ内のアドレスを転送できますが、 が指すメモリ内で操作を実行するには、何かにキャストする必要がありますvoid*

于 2012-09-21T12:45:51.350 に答える
5

ポインタはただではありませんint。それらは暗黙的にセマンティクスを持っています。

以下にいくつかの例を示します。

  • p->memberpタイプが何を指しているかを知っている場合にのみ意味があります。

  • p = p+1;ポイントするオブジェクトのサイズに応じて異なる動作をします(実際には、「p」が符号なし整数として見られる場合、それがポイントする型のサイズだけインクリメントされるという意味で)。

于 2012-09-21T12:46:56.730 に答える
2

「アドレスは常にint型」というあなたの仮定は間違っているからです。

たとえば、何らかの理由で、文字へのポインターが単語へのポインターよりも大きいコンピューター アーキテクチャを作成することは完全に可能です。C がこれを処理します。

また、もちろん、ポインターを逆参照することもできます。その場合、コンパイラーは、問題のアドレスで見つかると予想されるデータの型を知る必要があります。そうしないと、そのデータを処理するための適切な命令を生成できません。

検討:

char *x = malloc(sizeof *x);
*x = 0;

double *y = malloc(sizeof *y);
*y = 0;

これらの 2 つのスニペットは、まったく異なる量のメモリを書き込みます (または、割り当てが失敗した場合は爆発します。今のところ気にしないでください) が、実際のリテラル定数 (0intは ) はどちらの場合も同じです。ポインターの型に関する情報により、コンパイラーは適切なコードを生成できます。

于 2012-09-21T12:42:13.293 に答える
2

C では型のないポインターを非常に簡単に使用できvoid *ます。すべてのポインターに対して使用するだけです。私が考えることができる2つの理由から、これはかなりばかげています。

まず、型で指されているデータを指定することにより、コンパイラは多くのばかげた間違い、タイプミスなどからあなたを救います。代わりに、この情報をコンパイラから奪うと、問題になるはずのないものをデバッグするのに多くの時間を費やすことになります。

さらに、おそらく「ポインター演算」を使用したことがあります。たとえば、int *pInt = &someInt; pInt++;-- これはポインタをメモリ内の次の整数に進めます。これはタイプに関係なく機能し、適切なアドレスに進みますが、コンパイラがポイントされているもののサイズを知っている場合にのみ機能します。

于 2012-09-21T12:45:43.263 に答える
0

ほとんどの場合、あなたの後にコードを読んで、そのアドレスに何が格納されているかを知ることができます。また、コードでポインター演算を行う場合、データ型のサイズがコンパイル前に知られています。

于 2012-09-21T12:45:55.313 に答える
0

ポインターの型は、一度に操作を実行できるバイト数をコンパイラーに伝えるためです。

例: の場合char、1 バイトのみ。また、2 バイトの int の場合は異なる場合があります。

于 2012-09-21T12:46:30.263 に答える