A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

allen405

初级黑马

  • 黑马币:24

  • 帖子:7

  • 精华:0

© allen405 初级黑马   /  2014-4-27 00:41  /  918 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 allen405 于 2014-4-27 22:53 编辑

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

  printf("%d %d\n", *(a + 1), *(p - 1));
  return 0;
}
求详细解析

评分

参与人数 1技术分 +1 收起 理由
jing迪 + 1

查看全部评分

3 个回复

倒序浏览
int *p = (int *)(&a + 1); 后面括号中,指针指向的位置已经越界,指针指向的是数组a第5个元素后面的一个内存位置。将这个地址赋给指针p。
printf("%d %d\n", *(a + 1), *(p - 1)); 前面括号中的a,取出的是数组的首元素的地址,既a[0]的位置,位置加1,也就是指向数组的第二个元素,既a[1],结果为2。

&a取出的是int类型的5个成员的数组首元素的指针,内存中占据的存储空间为20,加1,就是在后面再加这样一个存储空间[指针跨度为20(理论上)]。让指针p指向后面加的这个指针的首元素。
*(a+1)这里的a,是取出的a[0]的存储位置(为4个字节),加1,就是指针指向下一个4个字节的位置。指针跨度为[4个字节(因为int类型在内存中占据4个字节)]
看明白上面,你就知道*(p - 1),他的值为什么是5了吧。
不明白请追问。  实在是不能画动态图,不然给你画个gif格式的图片,你看一眼就懂了。

评分

参与人数 1技术分 +1 收起 理由
jing迪 + 1

查看全部评分

回复 使用道具 举报
  1. int main(int argc, const char * argv[])
  2. {
  3. /*
  4.     int a[5] = {1, 2, 3, 4, 5};
  5.     printf("%lu\n", sizeof(&a)); // a是指针常量,&a 取指向int *类型的指针的地址 即指向指针的指针
  6.                                  // 无论指针指向什么类型的地址,指针占8字节
  7.    
  8.     printf(" &a地址:%#x\n &a+1地址:%#x\n", &a, &a + 1);
  9.     // &a 和 (&a + 1) 内存地址相差 20  5 * sizeof(int)

  10.     int *p = (int *)(&a + 1);  // 将指向指针的指针强制转化为指向int类型变量的指针
  11.    
  12.     printf("%i %i \n", *(a + 1), *(p + 1));
  13.    
  14.     return  0;
  15. */
  16.     int a[5] = {1, 2, 3, 4, 5};
  17.     int *p = a + 1; // p指针变量,指向a[1]
  18.    
  19.     printf("a[1] = %i\np[1] = %i\n", a[1], p[1]);
  20.    
  21.     return 0;
  22.    
  23.     /*
  24.      a[1] = 2
  25.      p[1] = 3
  26.      */
  27. }
复制代码


回复 使用道具 举报
2楼的哥们,不大厚道哟。  你这写完回复,看了我得回复,再改成这样。得,也苦了你了。楼主能看明白就好。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马