第一问:下面程序的结果:
... {
int a[5]=...{1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
int *ptr=(int *)(&a+1); //指向整个数组末尾
int *ptr=(int *)(a+1); //指向a的下一个元素
事实证明:
*(a+1)就是a[1],*(ptr-1)就是a[4]
执行结果是2,5
&a+1系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
1.int * 是强制转换为int型指针。
2.对于int a[5]={1,2,3,4,5};a就是数组首地址。a+1是首地址+1. a 等价于&a[0].
3. &a不是首地址,&a是指向首地址的指针,可以看作是整个数组的指针。&a+1是 a[5]后面的地址.&a[0] 才是数组首地址。&a+1≠a+1 int a[5]={1,2,3,4,5};
//
// &a 指向是 a[5]的类型, &a + 1指向下一个a[5]类型,等同于指向第6(索引为5)个int
// int *ptr = (int*)(&a + 1) 强制转换指针为int*
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1)); //ptr - 1 指向上一个int,即索引号为4的整数
int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (*)[5];
而指针加1要根据指针类型加上一定的值,
不同类型的指针+1之后增加的大小不同
a是长度为5的int数组指针,所以要加 5*sizeof(int)
所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)
所以prt-1只会减去sizeof(int*)
int *ptr=(int *)(&a);
0040105B lea eax,[ebp-14h] ;a[0]的地址
0040105E mov dword ptr [ebp-18h],eax
int *ptr=(int *)(&a+1);
0040105B lea eax,[ebp] ;这里比上边增加了14h,即20个字节
0040105E mov dword ptr [ebp-18h],eax
&a是数组指针,其类型为 int (*)[5];
谭浩强的c语言编程里讲的很清楚!