1.
int main()
{
int a[3][2] = { (0,1),(2,3),(4,5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
解析:a是一个3行2列的二维数组,对他进行初始化时大括号里面是逗号表达式,根据逗号表达式可以得到a数组中元素为1,3 ,5,0,0。p里面存放的是a[0]的地址,a[0]表示第一行的地址,表示首元素地址,也就是a[0][0]的地址,&a[0][0],p[0]相当于*(p+0),得到1
2.
int main()
{
int a[5] = { 1,2,3,4,5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
解析:*(a + 1)中的a表示首元素的当址,加1也就是向后访问4个字节,对其解引用就是2
*(ptr - 1)中ptr是数组a向后跳过一个数组的地址,可以参考下图:
3.
int main()
{
int a[4] = {1,2,3,4};
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
解析:ptr1[-1]也就相当于*(ptr1+(-1)),ptr1里面存放的是数组a向后跳过一个整形数组的地址,减一也就是指向元素4的那个地址。第五行代码中将a的类型强制转换为整型,整形加一就是普通的算术运算,在对其进行强制类型转换为整型指针,指针访问的是4个字节,详细如下图(VS编译器默认是小端存储地址的)