4

単項演算子++が数値に1を加算することを私は知っています。ただし、intポインターで実行すると、4(システム上のintのサイズ)だけ増加することがわかりました。なぜこれを行うのですか?たとえば、次のコードです。

int main(void)
{
  int *a = malloc(5 * sizeof(int));
  a[0] = 42;
  a[1] = 42;
  a[2] = 42;
  a[3] = 42;
  a[4] = 42;
  printf("%p\n", a);
  printf("%p\n", ++a);
  printf("%p\n", ++a);
  return 0;
}

それぞれの間に4の差がある3つの数値を返します。

4

9 に答える 9

6

これはCのやり方です-完全な説明は仕様のセクション6.5.6加法演算子のパラグラフ8にあります:

整数型の式がポインターに加算またはポインターから減算されると、結果はポインターオペランドの型になります。ポインタオペランドが配列オブジェクトの要素を指し、配列が十分に大きい場合、結果は元の要素からオフセットされた要素を指し、結果の配列要素と元の配列要素の添え字の差が整数式に等しくなります。言い換えると、式が配列オブジェクトのiP番目の要素を指している場合、式(同等に、)および(値はn)は、それぞれi + n番目およびiを指します。(P)+NN+(P)(P)-NN− <i>配列オブジェクトのn番目の要素(存在する場合)。さらに、式Pが配列オブジェクトの最後の要素を指している場合、式は配列オブジェクトの最後の要素の1つ先を指し、式が配列オブジェクトの最後の要素の1つ先を指し(P)+1ている場合、式は最後の要素を指します。配列オブジェクトの。ポインタオペランドと結果の両方が同じ配列オブジェクトの要素を指している場合、または配列オブジェクトの最後の要素を1つ過ぎている場合、評価によってオーバーフローが発生することはありません。それ以外の場合、動作は定義されていません。結果が配列オブジェクトの最後の要素の1つ過ぎを指している場合、評価される単項演算子のオペランドとして使用されないものとします。Q(Q)-1*

これをプレフィックス演算子の使用に関連付けるには、セクション6.5.3.1プレフィックスのインクリメントおよびデクリメント演算子の段落2++も読む必要があります。

プレフィックス++演算子のオペランドの値がインクリメントされます。結果は、インクリメント後のオペランドの新しい値です。式++Eはと同等(E+=1)です。

また、セクション6.5.16.2複合代入、パラグラフ3:

形式op複合代入は、左辺値が1回だけ評価されるという点でのみ、単純代入式opとは異なります。E1 = E2E1 = E1 (E2)E1

于 2011-02-15T00:53:55.637 に答える
3

intポインタの宣言された型であるのサイズだけポインタの位置をインクリメントします。

int *anは、「int」が格納されていると言っているメモリ内の場所への単なるポインタであることを忘れないでください。ポインタに++移動すると、(型のサイズによって)1つの場所に移動します。この場合、値は「4」高くなりsizeof(int)==4ます。

于 2011-02-15T00:52:04.263 に答える
2

この理由は、次のステートメントを真にするためです。

*(ptr + n) == ptr[n]

これらは互換的に使用できます。

于 2011-02-15T00:53:49.193 に答える
1

ポインタ演算では、ポインタに1を追加すると、それが指す型のサイズが追加されます。

したがって、特定の場合:

TYPE * p;

pに追加すると、実際には。ずつ増加しsizeof(TYPE)ます。この場合、intのサイズは4です。

この関連する質問を参照してください

于 2011-02-15T00:51:56.433 に答える
1

「C」では、ポインタ演算は常に、ポイントされているオブジェクトのサイズによってスケーリングされるためです。少し考えてみると、「正しいこと」であることがわかります。

于 2011-02-15T00:52:53.750 に答える
1

これは、途中で整数にアクセスし始めないようにするためです。

于 2011-02-15T00:52:58.247 に答える
0

Thats simple, cause when it comes down to pointer, in your case an integer pointer, a unary increment means INCREMENT THE MEMORY LOCATION BY ONE UNIT, where ONE UNIT = SIZE OF INTEGER .

This size of integer depends from compile to compiler, for a 32-bit and 16-bit it is 4bytes, while for a 64-bit compiler it is 8bytes.

Try doing the same program with character datatype, it will give difference of 1 byte as character takes 1 byte.

In Short, the difference of 4's that you've come across is the difference of SIZE OF ONE INTEGER in memory.

Hope this helped, if it didn't i'll be glad to help just let me know.

于 2011-02-15T06:43:19.397 に答える
0

ポインタは参照ではないため;)。これは値ではなく、メモリ内の単なるアドレスです。ポインタの値を確認すると、その数値になり、場合によっては大きくなり、そのメモリ位置に格納されている実際の値とは無関係になります。たとえば、「 2000000 printf("%p\n", a);」を出力します。これは、ポインタがマシンのメモリの2000000番目のバイトを指していることを意味します。そこにどのような価値が保存されているかはほとんどわかりません。

これで、ポインタはそれが指すタイプを認識します。あなたの場合は整数。整数は4バイトの長さであるため、ポインタが指す次の「セル」にジャンプする場合は、2000004である必要があります。これはさらに1整数なのでa++、完全に理にかなっています。

42ところで、 (あなたの例から)取得したい場合は、以下を指す値を出力してください:printf("%d\n", *a);

これが理にかなっていることを願っています;)

于 2011-02-15T00:56:31.970 に答える
0

「なぜこれを行うのですか?」なぜあなたはそれが他の何かをすることを期待するのですか?ポイントをインクリメントすると、それがポインタであるタイプの次のアイテムをポイントします。

于 2011-02-15T12:21:15.057 に答える