C配列ポインタ++操作まとめ
3743 ワード
今日は
まず、次の
心に答えがあるかもしれない
また、
何の違いもありませんが、本当にそうですか?答えは否定的であり、
結果は予想と一致した.
操作完了
もちろん、このとき
別の例を見てみましょう
上の分析によれば、簡単に
今私たちは
出力の場合
でも、
これは、
このロゴは一致しています
したがって、
*p++
のコードについて見ましたが、これらを一度コードしてまとめました.まず、次の
C
コードを見てください.int array[5] = {1,2,3,4,5};
int *p = array;
printf("---- p = %p
", p);
printf("---- *p++ = %d
", *p++);
printf("---- p = %p
", p);
心に答えがあるかもしれない
---- p = 0x7ffee30c2aa0
---- *p++ = 1
---- p = 0x7ffee30c2aa4
*p++
については、*p
がポインタp
に対して自己加算を実行することを先に取得し、自己加算演算子は右結合であるため、*p++
と*(p++)
の操作については、結果は一致し、++
演算子の優先度は*
より高いが、 ++
であるため、そのため、*p
演算を率先して実行し、p++
を実行する.printf("---- *(p++) = %d
", *(p++));
---- *(p++) = 1
また、
p
ポインタにとって、自己加算演算はp
が指すメモリアドレス+1
動作であるが、この+1
動作はどのように実行すればよいのだろうか.オブジェクトが初期化されるときにメモリアドレスを申請する必要があることを知っています.一般的にはmalloc()
で実行されます.動的にメモリアドレスを申請するときはcount * malloc(sizeof( ))
を実行します.これは、コンピュータにこのメモリアドレスを申請して変数を記憶する必要があることを示し、変数のタイプに応じてこのメモリ領域を平均的にcount
ブロックに分ける必要があります.1ブロックあたりのメモリサイズはsizeof( )
です.この例に戻ると、変数タイプはint
、sizeof(int) = 4
であり、コンソールのアドレスからもわかりやすいように、p++
を実行すると、p
が指すメモリアドレスは4バイト移動し、対応配列は、現在*p
が指すarray
の数字2
の位置になっている.printf("---- *p = %d
", *p);
---- *p = 2
++
にとって、*p++
と*(p++)
の結果はまったく同じである以上、(*p)++
は?printf("---- (*p)++ = %d
", (*p)++);
---- (*p)++ = 1
何の違いもありませんが、本当にそうですか?答えは否定的であり、
*p++
に対して、自増演算子の作用対象はp
であり、p
が指すarray
の位置として表現され、本来はarray[0]
を指し、*p++
を実行した後、p
はarray[1]
を指す.一方、(*p)++
では、加算演算子の作用対象は(*p)
、すなわちarray[0]
の値であり、ポインタp
が指す特定の位置については何の変化もない.printf("---- array = ");
for(int i=0; i
結果は予想と一致した.
---- array = 2 2 3 4 5
操作完了
++
の場合、 ++
printf("---- *++p = %d
", *++p);
printf("---- *p = %d
", *p);
---- *++p = 2
---- *p = 2
もちろん、このとき
*++p
は*(++p)
と同等であり、演算子は先に増加してからアドレス取り操作を行う.別の例を見てみましょう
int a[5] = {1, 2, 3, 4, 5};
int *ptr = (int *)(&a + 1);
printf("%d, %d
", *(a + 1), *(ptr+1));
上の分析によれば、簡単に
*(a + 1) = 2;
今私たちは
int *p = a;
出力の場合
printf("%p, %p
", &a, p);
0x7ffee3993aa0, 0x7ffee3993aa0
でも、
int *ptr = (int *)(&a + 1); int *ptr = (int *)(p + 1);
これは、
&a
がa
の配列全体を表し、p
は配列の要素の1つだけを表しているためであり、私たちの前の分析によると、+1
の操作を実行する際に、本当に加えられたのはsizeof( )
であり、sizeof(a) = 20; // 5 * sizeof(int) = 20;
sizeof(*p) = 4;
このロゴは一致しています
printf("%p, %p
", &a, ptr);
0x7ffeea171aa0, 0x7ffeea171ab4 //16 , 20
したがって、
int *ptr = (int *)(&a + 1);
にとって、&a + 1
はa + 5
に等しく、ptr + 1
はa + 6
に相当し、*ptr
はすでに a
を指していないので、*(ptr+1)
の結果は未知である.もちろん*(ptr-1)
に変えるとa + 4
に相当し、結果は5
になります.