C言語ポインタ--面接問題


ある人はグループの中で1本の試験問題を発表して、少し勉強して、試験の学習環境は32ビット機です
#include <stdio.h>

int main()  
{  
    int a[5] = { 1, 2, 3, 4, 5 };
    int *p1  = (int*)(&a + 1);  
    int *p2  = (int *)((int)a + 1);  

    printf("0x%x, 0x%x
", p1[-1], *p2); return 0; }

変数aのメモリアドレスは:0 x 0034 fc 50まずp 1を分析する
&aは配列ポインタ、タイプは「int(*)[5]」、配列ポインタは配列ヘッダ要素のアドレスを指すポインタ
&aのメモリアドレスは:0 x 0034 fc 50
&a+1ポインタを1つ追加して、1つの要素を後ろに移動します.ここでの要素タイプは「int(*)[5]」で、その空間サイズは20バイトなので、
&a+1のメモリアドレスは、0 x 0034 fc 64(0 x 0034 fc 50+0 x 14)
p 1のメモリアドレスは、0 x 0034 fc 64
p 1[-1]配列の下に負の数をマークし、要素を前に移動します(注意:配列境界はコンパイル時と実行時にエラーが発生しません.不正なメモリが操作されない限り).
p 1[-1]要素が存在するアドレスは、0 x 0034 fc 60
したがって,p 1[−1]のアドレスはa+4のアドレスであることが分かる.
p1[-1] == *(a + 4) == 5
分析を続けるp 2
(int)aの値は0 x 0034 fc 50
(int)a+1=0 x 0034 fc 51
メモリ構造を分析し、テスト環境のバイト順はlittle endian
01 00 00 00 02 00 00 00 03 00 0...
*p 2=0 x 200000