0

次のようなコードに出くわしました:

#include <stdio.h>

int main(void)
{
 int a[5] = { 1, 2, 3, 4, 5};
 int *ptr = (int*)(&a + 1);
 int *ptr2 = (int*) &a;
 ptr2 +=1 ;
 printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2 );
 return 0;
}

ポインター演算は、この行を除いて私のためにそれを行います:

int *ptr = (int*)(&a + 1);

未定義の動作ですか?5逆参照を行うのはなぜ*(ptr - 1)ですか?

4

3 に答える 3

3

のサイズaは「5int秒」です。したがって、ポインタ演算はのサイズの単位で行われるため、のすべてを超え&a + 1た最初のメモリ位置を参照します。aa

于 2012-09-27T14:36:34.170 に答える
2

やってみて!

int a[5] = {1, 2, 3, 4, 5};
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1);

0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0

それで、それは私たちに何を教えてくれますか?

0xbfa4038c == 0xbfa4038cつまりa == &a。これは、配列 or の最初の要素のアドレスですa[0]

*(a+1)int のサイズは 4 であり、 == (配列の 2 番目の要素) であることがわかっています。a[1]これは次のように証明されます。

0xbfa4038c + 0x4 = 0xbfa40390つまりa + one int = address of the next element

したがって、 が表示された場合、配列に = 5 個の要素&a+1 == 0xbfa403a0があることを意味します。((0xa0-0x8c)/4)これは無効であることがわかっているa[5]ので、配列の末尾を通過したことになります。

あなたが取るならば:

int *ptr = (int*)(&a + 1); //one passed last element in the array
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference

それがあなたが得る理由です5

于 2012-09-27T14:52:44.660 に答える
0

型 T の n 要素の配列の場合、最初の要素のアドレスは型 'pointer to T' を持ちます。配列全体のアドレスの型は「T 型の n 要素の配列へのポインタ」です。

int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes, 
         //ptr=&a+1: next element =adress of a +20 bytes.
         //ptr - 1 = address of a +16 = address of last a's element = address of 5
于 2012-10-01T11:11:46.687 に答える